如何使用 jq 生成输入中存在的两个数组的笛卡尔积 JSON
How to use jq to produce a cartesian product of two arrays present in the input JSON
我希望能够使用 jq
在输入 JSON 中输出 2 个数组的 'product'... 例如,给定以下输入 JSON:
{
"quantities": [
{
"product": "A",
"quantity": 30
},
{
"product": "B",
"quantity": 10
}
],
"portions": [
{
"customer": "C1",
"percentage": .6
},
{
"customer": "C2",
"percentage": .4
}
]
}
我想生成以下输出(或类似...):
[
{
"customer": "C1",
"quantities": [
{
"product": "A",
"quantity": 18
},
{
"product": "B",
"quantity": 6
}
]
},
{
"customer": "C2",
"quantities": [
{
"product": "A",
"quantity": 12
},
{
"product": "B",
"quantity": 4
}
]
}
]
换句话说,对于每个部分,使用其百分比值,并将其应用于每个产品数量。给定 2 个数量和 2 个部分应该产生 4 个结果。给定 3 个数量和 2 个部分应该产生 6 个结果,等等...
我尝试使用 foreach
过滤器,但无济于事...
我想这会做你想要的。
[
.quantities as $q
| .portions[]
| .percentage as $p
| {
customer,
quantities: [
$q[] | .quantity = .quantity * $p
]
}
]
既然你表示你想要笛卡尔积,并且你只给出了样本输出作为你正在寻找的东西的指示,可能值得一提的是可以非常简单地获得笛卡尔积:
.portions[] + .quantities[]
这会产生如下对象:
{
"product": "B",
"quantity": 10,
"customer": "C2",
"percentage": 0.4
}
然后您可以使用 reduce
或(效率较低,group_by
)以您真正想要的任何形式获取数据。
例如,假设 .customer 始终是一个字符串,我们可以转换
输入请求格式如下:
def add_by(f;g): reduce .[] as $x ({}; .[$x|f] += [$x|g]);
[.quantities[] + .portions[]]
| map( {customer, quantities: {product, quantity: (.quantity * .percentage)}} )
| add_by(.customer; .quantities)
| to_entries
| map( {customer: .key, quantities: .value })
我希望能够使用 jq
在输入 JSON 中输出 2 个数组的 'product'... 例如,给定以下输入 JSON:
{
"quantities": [
{
"product": "A",
"quantity": 30
},
{
"product": "B",
"quantity": 10
}
],
"portions": [
{
"customer": "C1",
"percentage": .6
},
{
"customer": "C2",
"percentage": .4
}
]
}
我想生成以下输出(或类似...):
[
{
"customer": "C1",
"quantities": [
{
"product": "A",
"quantity": 18
},
{
"product": "B",
"quantity": 6
}
]
},
{
"customer": "C2",
"quantities": [
{
"product": "A",
"quantity": 12
},
{
"product": "B",
"quantity": 4
}
]
}
]
换句话说,对于每个部分,使用其百分比值,并将其应用于每个产品数量。给定 2 个数量和 2 个部分应该产生 4 个结果。给定 3 个数量和 2 个部分应该产生 6 个结果,等等...
我尝试使用 foreach
过滤器,但无济于事...
我想这会做你想要的。
[
.quantities as $q
| .portions[]
| .percentage as $p
| {
customer,
quantities: [
$q[] | .quantity = .quantity * $p
]
}
]
既然你表示你想要笛卡尔积,并且你只给出了样本输出作为你正在寻找的东西的指示,可能值得一提的是可以非常简单地获得笛卡尔积:
.portions[] + .quantities[]
这会产生如下对象:
{
"product": "B",
"quantity": 10,
"customer": "C2",
"percentage": 0.4
}
然后您可以使用 reduce
或(效率较低,group_by
)以您真正想要的任何形式获取数据。
例如,假设 .customer 始终是一个字符串,我们可以转换 输入请求格式如下:
def add_by(f;g): reduce .[] as $x ({}; .[$x|f] += [$x|g]);
[.quantities[] + .portions[]]
| map( {customer, quantities: {product, quantity: (.quantity * .percentage)}} )
| add_by(.customer; .quantities)
| to_entries
| map( {customer: .key, quantities: .value })