【问题标题】:JQ: How to join arrays by key?JQ:如何按键加入数组?
【发布时间】:2022-10-07 14:03:40
【问题描述】:

如何使用存储在字典中的类别扩展数组?

例如。对于以下输入,

{\"weigths\":
  [
    {\"name\":\"apple\",\"weigth\":200},
    {\"name\":\"tomato\", \"weigth\":100}
  ],
 \"categories\":
 [
   {\"name\":\"apple\",\"category\":\"fruit\"},
   {\"name\":\"tomato\",\"category\":\"vegetable\"}
 ]
}

我需要一种高效的方法将各自的category 附加到weights 中的每个对象,从而产生输出:

{\"weigths\":
  [
    {\"name\":\"apple\",\"weigth\":200, \"category\": \"fruit\"},
    {\"name\":\"tomato\", \"weigth\":100, \"category\": \"vegetable\"}
  ],
}

是给JOIN/4 的吗? (我从未尝试过)


更新:

理想情况下,我想处理类别的非 SQL 对象:完整输入看起来像这样

{\"weigths\":
  [
    {\"name\":\"apple\",\"weigth\":200},
    {\"name\":\"orange\", \"weigth\":300}
    {\"name\":\"tomato\",\"weigth\":100},
    {\"name\":\"spinach\",\"weigth\":50},
  ],
 \"categories\":
 {
   \"fruit\": [\"apple\", \"orange\"],
   \"vegetable\": [\"tomato\", \"spinach\"]
 }
}

...仍然得到类似的输出:

{\"weigths\":
  [
    {\"name\": \"apple\", \"weigth\": 200, \"category\": \"fruit\"},
    {\"name\": \"orange\", \"weigth\": 300, \"category\": \"fruit\"},
    {\"name\": \"tomato\", \"weigth\": 100, \"category\": \"vegetable\"}
    {\"name\": \"spinach\", \"weigth\": 50, \"category\": \"vegetable\"}
  ],
}

    标签: jq


    【解决方案1】:

    使用 SQL 风格的运算符 JOININDEX 将是:

    {weights: [JOIN(INDEX(.categories[]; .name); .weigths[]; .name; add)]}
    
    {
      "weights": [
        {
          "name": "apple",
          "weigth": 200,
          "category": "fruit"
        },
        {
          "name": "tomato",
          "weigth": 100,
          "category": "vegetable"
        }
      ]
    }
    

    Demo

    【讨论】:

    • 太感谢了!更新部分的任何机会(在问题中的“更新:”下)?
    • @wassrubleff 老实说,我不明白更新问题。 orangespinach 应该从哪里来?您是否正在寻找像jq '.categories | group_by(.category) | map({(first.category): map(.name)}) | {categories: add}' 这样的分组?
    • 使用完整的输入数据扩展了更新。
    • @wassrubleff 然而,你没有解释这两个新值应该来自哪里。也许您提供的输入与您使用的输入不同?您是否尝试过我之前评论中的group_by?这样,使用|= 更新(而不仅仅是查询)以保留原始结构:jq '.categories |= (group_by(.category) | map({(first.category): map(.name)}) | add)'
    • 更新是关于具有不同的输入:所有要归类为水果的项目的单独列表,另一个要归类为蔬菜的项目列表。这是我实际拥有的输入;我很好奇是否有更高效的方式来处理这些数据。
    【解决方案2】:

    您可能有兴趣查看 ~Q(发音为“unquery”),这是我最近发布的一种查询语言,它就像 jq 一样可以作为命令行工具运行。

    https://github.com/xcite-db/Unquery

    在第一种情况下,查询将是:

    {
        "#var cat:categories[]": {
              "$(name)":"category"
        },
        "#return:weigths[]": [{
           "{}:" : ".",
           "category":"$var(cat).$(name)"
        }]
    }
    

    在更新的示例中,查询是:

    {
        "#var cat: categories:{}:[]": {
              "$(.)": "$key"
        },
        "#return:weigths[]": [{
           "{}:": ".",
           "category":"$var(cat).$(name)"
        }]
    }
    

    无论哪种情况,诀窍都是首先生成从水果到类别的映射,然后使用此映射将类别添加到每个条目。所以区别只在第一部分(生成地图)。

    ~Q 中的变量可以包含任何 JSON 值/文档。编码:

        "#var cat: categories:{}:[]": {
              "$(.)": "$key"
        },
    

    将内存中的categories 转换为:

    {
        "apple": "fruit",
        "orange": "fruit",
        "spinach": "vegetable",
        "tomato": "vegetable"
    }
    

    之后,您可以使用它来检索带有$var(cat).$(name) 的类别。如果您有不同的类别结构,您需要做的就是更改该部分代码以从类别结构生成映射。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2017-08-30
      • 2016-07-09
      • 2019-12-10
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多