从 JQ 中的列表中提取多个子元素时,如何避免创建叉积?

How do I avoid creating a cross product when extracting multiple sub-elements from a list in JQ?

我正在从供应商处获取产品信息。它有无数个字段,但我已将其缩减为仅相关字段。我预计该解决方案与 map() 有关,但我无法完全理解它。

当我尝试从子词典中获取多个字段时,它会进行叉积。在此示例中,我希望返回 2 行,但我得到 4。

Fiddle
预期输出:

{
  "sku": "1234",
  "desc": "Pink Ring",
  "img_url": "https://provider.com/rings/1234_A",
  "img_angle": "ViewA"
}
{
  "sku": "1234",
  "desc": "Pink Ring",
  "img_url": "https://provider.com/rings/1234_B",
  "img_angle": "ViewB"
}

起始数据:

{
  "Products": [
    {
      "SKU": "1234",
      "Description": "Pink Ring",
      "RingSize": 7,
      "Images": [
        {
          "FullUrl": "https://provider.com/rings/1234_A",
          "SortOrder": 1,
          "Angle": "ViewA"
        },
        {
          "FullUrl": "https://provider.com/rings/1234_B",
          "SortOrder": 2,
          "Angle": "ViewB"
        }
      ]
    }
  ]
}

然后我通过这个过滤器传递它:

.Products[] | { sku: .SKU, desc: .Description, img_url: .Images[].FullUrl, img_angle: .Images[].Angle }

这给了我以下数据:

{
  "sku": "1234",
  "desc": "Pink Ring",
  "img_url": "https://provider.com/rings/1234_A",
  "img_angle": "ViewA"
}
{
  "sku": "1234",
  "desc": "Pink Ring",
  "img_url": "https://provider.com/rings/1234_A",
  "img_angle": "ViewB"
}
{
  "sku": "1234",
  "desc": "Pink Ring",
  "img_url": "https://provider.com/rings/1234_B",
  "img_angle": "ViewA"
}
{
  "sku": "1234",
  "desc": "Pink Ring",
  "img_url": "https://provider.com/rings/1234_B",
  "img_angle": "ViewB"
}

这就是我所希望的。你可以看到 URL_A 和 ANGLE_A 不与 URL_B 和 ANGLE_B.

交叉相乘
{
  "sku": "1234",
  "desc": "Pink Ring",
  "img_url": "https://provider.com/rings/1234_A",
  "img_angle": "ViewA"
}
{
  "sku": "1234",
  "desc": "Pink Ring",
  "img_url": "https://provider.com/rings/1234_B",
  "img_angle": "ViewB"
}

请不要假设您可以相信 img_urlimg_angle 具有相互引用的值 - 您绝对不能,这仅用于说明目的。

我已经尝试了几种方法,它们一直给我一个叉积,但实际上并没有改变输出,比如 { sku: .SKU, desc: .Description } + { img_url: .Images[].FullUrl } + { img_angle: .Images[].Angle }

我也尝试过改编 this recipe book and this cheat sheet 的食谱。我无法获得任何在运行时不会呕吐的有用信息。

这是您要找的吗:

.Products[] | {sku: .SKU, desc: .Description} + (
  .Images[] | {img_url: .FullUrl, img_angle: .Angle}
)

Fiddle

您可以看到 STREAM as $var 创建了一个 foreach 循环。

.Products[] |
.Images[] as $img |
{ sku: .SKU, desc: .Description, img_url: $img.FullUrl, img_angle: $img.Angle }

jqplay


我们可以证明这等同于其他答案。

让我们从分解 $img.

开始
.Products[] |
.Images[] as $img |
{ sku: .SKU, desc: .Description } +
( $img | { img_url: .FullUrl, img_angle: .Angle } )

现在我们可以内联变量,因为 1) 它只使用了一次,并且 2) 主题 (.) 相同。

.Products[] |
{ sku: .SKU, desc: .Description } +
( .Images[] | { img_url: .FullUrl, img_angle: .Angle } )

我们已经到了。