【问题标题】:jq - sorting value by a related valuejq - 按相关值排序值
【发布时间】:2017-04-08 21:53:24
【问题描述】:

基本上,我只是想列出一份按各自种子排序的 NCAA March Madness 球队名单。

我正在使用来自http://data.ncaa.com/jsonp/scoreboard/basketball-men/d1/2017/03/17/scoreboard.html 的 JSON 文件。它实际上是 JSONP,但我在解析之前将其转换为 JSON:

jq -s -R  '.[1+index("("): rindex(")")] | fromjson'

将其输入以下命令,我可以生成一个不错的团队列表:

jq -r '.scoreboard[].games[] | select(.bracketRound=="First Round" and .bracketRegion=="EAST") | .home,.away | .nameRaw'

...但我希望他们按照他们的种子顺序排列。我尝试以各种方式使用 sort 和 sort_by 均无济于事。我没有想法。

【问题讨论】:

    标签: json sorting jq


    【解决方案1】:

    根据您的数据,以下过滤器:

    [ .scoreboard[].games[]
      | select(.bracketRound=="First Round" and .bracketRegion=="EAST")
      | (.home, .away) ]
    | sort_by(.teamSeed | tonumber) 
    | .[]
    | [.teamSeed, .nameRaw ]
    

    产生:

    ["2","Duke"]
    ["3","Baylor"]
    ["6","SMU"]
    ["7","South Carolina"]
    ["10","Marquette"]
    ["11","USC"]
    ["14","New Mexico St."]
    ["15","Troy"]
    

    如果您只想要“nameRaw”值,请将过滤器的最后一行替换为:| .nameRaw

    请注意,此处需要tonumber,因为种子值以字符串形式给出。

    处理多个顶级对象

    在评论中,OP 给出了一个包含两个顶级对象的 pastebin (https://pastebin.com/1eTAX4y3),每个对象都有一个“记分牌”。因此,让我们考虑任意数量的此类对象的情况。

    为了清楚起见,我们首先定义一个函数,用于从带有“记分板”的 JSON 对象中选择主/离对象:

    def games:
      [.scoreboard[].games[]
       | select(.bracketRound=="First Round" and .bracketRegion=="EAST")
       | (.home, .away) ] ;
    

    使用 -s 命令行选项,我们可以确保 JSON 输入是一个对象数组。 games产生的数组可以用add组合:

    map(games)
    | add
    | sort_by(.teamSeed | tonumber) 
    | .[]
    | [.teamSeed, .nameRaw ]
    

    鉴于 pastebin 数据,使用命令行选项 -s 和 -c 选项的调用会产生:

    ["1","Villanova"]
    ["2","Duke"]
    ["3","Baylor"]
    ["4","Florida"]
    ["5","Virginia"]
    ["6","SMU"]
    ["7","South Carolina"]
    ["8","Wisconsin"]
    ["9","Virginia Tech"]
    ["10","Marquette"]
    ["11","USC"]
    ["12","UNCW"]
    ["13","East Tenn. St."]
    ["14","New Mexico St."]
    ["15","Troy"]
    ["16","Mt. St. Mary's"]
    

    【讨论】:

    • 我也几乎拥有它。只需要'tonumber'。但是,我遇到了一个我没有提及的问题。我将两个 JSON 文件合并在一起,因为第一轮播放了两天(因此两个单独的文件)。我使用 jq -s .[] *.json 来做到这一点。但是当使用你的过滤器时,它会将它们分开而不是把它们排序在一起。这是生成的 JSON 文件以供参考:pastebin.com/1eTAX4y3
    • 现在我正在查看那个“合并”的 JSON 文件,它甚至根本没有真正合并...我明白为什么将它们排序在一起时会出现问题。它们是两个独立的数组。有没有办法正确合并这些?
    【解决方案2】:

    这是你想要的吗?

    jq -r '
    def NameAndSeed(f): f | {nameRaw, "teamSeed" : (.teamSeed | tonumber)};
    [ 
      .scoreboard[].games[]
      | select(.bracketRound=="First Round" and .bracketRegion=="EAST")
      | NameAndSeed(.home), NameAndSeed(.away)
    ]
    | sort_by(.teamSeed) 
    | .[].nameRaw'
    

    为了让 sort_by 做我认为你想做的事,我将对象放在一个数组中,并将 teamSeed 值转换为数字。

    【讨论】:

      猜你喜欢
      • 2020-12-23
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2023-03-17
      • 2021-11-10
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多