【问题标题】:Filter objects using multiple conditions including comparing two object fields使用多个条件过滤对象,包括比较两个对象字段
【发布时间】:2018-06-14 19:59:57
【问题描述】:

拥有一个 JSON 对象列表,并尝试根据最小值检查和两个字段之间的比较来过滤它们。

{
  "preview": false,
  "init_offset": 0,
  "messages": [],
  "fields": [
    {
      "name": "A"
    },
    {
      "name": "B"
    },
    {
      "name": "Diff"
    },
    {
      "name": "Threshold"
    }
  ],
  "results": [
    {
      "A": "foo",
      "B": "bar",
      "Diff": "1095",
      "Threshold": "1200"
    },
    {
      "A": "baz",
      "B": "bux",
      "Diff": "81793",
      "Threshold": "0"
    },
    {
      "A": "quux",
      "B": "quuz",
      "Diff": "194"
    },
    {
      "A": "moo",
      "B": "goo",
      "Diff": "5000",
      "Threshold": "2000"
    }
 ]
}

离我最近的是

.results
| map(.Threshold //= "0")
| .[]
| select((.Threshold|tonumber > 0) and 
         (.Diff|tonumber > .Threshold|tonumber))

但这给出了一个

Cannot index string with string "Threshold"

错误。

基本上我想返回 Diff 大于非零阈值的所有结果。所以在这种情况下:

{
  "A": "moo",
  "B": "goo",
  "Diff": "5000",
  "Threshold": "2000"
}

使用 jq 1.5 FWIW。

【问题讨论】:

    标签: syntax jq


    【解决方案1】:

    您只是缺少一些括号。比较:

    select((.Threshold|tonumber) > 0 and
           (.Diff|tonumber) > (.Threshold|tonumber))
    

    或者避免双重转换:

    select( (.Threshold|tonumber) as $t
            | $t > 0 and (.Diff|tonumber) > $t )
    

    你也可以稍微简化一下整个程序:

    .results[]
    | select( ((.Threshold // 0) | tonumber) as $t 
              | $t > 0 and (.Diff|tonumber) > $t )
    

    【讨论】:

    • 提供jq: error (at jq1:44): null (null) cannot be parsed as a number。没有Threshold键的对象需要jq '.results[] | select(.Threshold and (.Threshold | tonumber) as $t | $t > 0 and ((.Diff | tonumber) > $t))'
    • @RomanPerekrest - 我只是显示“选择”行,而不是完整的程序。您的替代方案也会改变语义。
    猜你喜欢
    • 2023-02-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-02-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多