代码之家  ›  专栏  ›  技术社区  ›  con

Perl6:按值排序散列并使用kv

  •  0
  • con  · 技术社区  · 5 年前

    我正在查看以下数据(JSON格式)

    {
      "FValidation_pipelineMTHXT_v4.5.1_refLibV2": "concordance2/f",
      "FValidation_pipelineLPJL": "concordance2/c",
      "FCompetenceRuns": "concordance2/b",
      "FWGS": "concordance2/a",
      "Falidation_pipelineMTHXT": "concordance2/e",
      "FValidation_pipelineLPJL_v4.5.1_refLibV2": "concordance2/d"
    }
    

    我试着按散列值排序

    for %files.kv -> $key, $value {
    

    提供所需的数据,但我希望对其进行排序。我试过20种不同的方法,但都不管用

    for %files.sort.kv  -> ($key, $value) {
    

    for %files.sort: *.value.kv  -> ($key, $value) {
    

    它的灵感来自 https://docs.perl6.org/routine/sort#(Map)_method_sort 一次又一次,但都没有效果:(

    如何按值对哈希进行排序?

    0 回复  |  直到 5 年前
        1
  •  7
  •   Brad Gilbert    5 年前

    .kv 返回平面序列。

    my %h = (
      a => 3,
      b => 2,
      c => 1,
    );
    
    say %h.kv.perl;
    # ("a", 3, "c", 1, "b", 2).Seq
    

    如果对其进行排序,则在不保留键及其关联值的情况下进行排序。

    say %h.kv.sort.perl;
    # (1, 2, 3, "a", "b", "c").Seq
    

    所以你想把它分类 之前 把两人分开。

    # default sort order (key first, value second)
    say %h.sort.perl;
    # (:a(3), :b(2), :c(1)).Seq
    
    say %h.sort: *.value;       # sort by value only (tied values are in random order)
    # (:c(1), :b(2), :a(3)).Seq
    say %h.sort: *.invert;      # sort by value first, key second
    # (:c(1), :b(2), :a(3)).Seq
    say %h.sort: *.kv.reverse;  # sort by value first, key second
    # (:c(1), :b(2), :a(3)).Seq
    

    排序后,可以将其作为成对对象的序列:

    # default $_
    for %h.sort: *.invert {
      say .key ~ ' => ' ~ .value
    }
    
    # extract as named attributes
    for %h.sort: *.invert -> (:$key, :$value) {
      say "$key => $value"
    }
    
    # more explicit form of above
    for %h.sort: *.invert -> Pair $ (:key($key), :value($value)) {
      say "$key => $value"
    }
    

    或者你可以在分类后把它们分开:
    (注意两层结构。)

    say %h.sort(*.invert).map(*.kv).perl;
    # (("c", 1).Seq, ("b", 2).Seq, ("a", 3).Seq).Seq
    say %h.sort(*.invert)».kv.perl;
    # (("c", 1).Seq, ("b", 2).Seq, ("a", 3).Seq).Seq
    
    # default $_
    for %h.sort(*.invert).map(*.kv) {
      say .key ~ ' => ' ~ .value
    }
    
    # extract inner positional parameters
    for %h.sort(*.invert).map(*.kv) -> ($k,$v) {
      say "$k => $v"
    }
    
    # `».kv` instead of `.map(*.kv)`
    for %h.sort(*.invert)».kv -> ($k,$v) {
      say "$k => $v"
    }
    

    你甚至可以在拆开两个物体后把它压平。

    say %h.sort(*.invert).map(*.kv).flat.perl;
    # ("c", 1, "b", 2, "a", 3).Seq
    say %h.sort(*.invert)».kv.flat.perl;
    # ("c", 1, "b", 2, "a", 3).Seq
    
    for %h.sort(*.invert).map(*.kv).flat -> $k, $v {
      say "$k => $v"
    }
    
    for %h.sort(*.invert)».kv.flat -> $k, $v {
      say "$k => $v"
    }
    

    (注意 ».method 只映射一个方法调用。绘制两个以上的地图 ».method1».method2 ,或者只使用map .map(*.method1.method2) .
    所以在 ».kv.flat 上面,只有 千伏 方法映射到值上。)

        2
  •  7
  •   ugexe    5 年前
    my %hash = :a<z>, :b<y>, :c<x>;
    
    for %hash.sort(*.value) {
        say $_.key;
        say $_.value;
    }
    
    推荐文章