英文:
Combine arrays of objects when matching criteria is fullfilled
问题
I have two top level arrays: products
and prices
. I have to move all those price
objects under product
where price.productId == product.id
. Note that there can be any number of products
and prices
and their relationships.
My current solution:
- copies all prices to every product
- tries to "remove" all those prices where ids don't match
The problem is I can't figure out how to match to the value of product.id
in the step #2. In my example below I have hardcoded the value, see the FIXME
comment.
I'm also open for better solutions if any.
Note also two TODO extra points (that might vanish with a more appropriate solution).
This is a simplified version of the actual problem to illustrate the point.
Input:
{
"products": [
{
"id": "PROD_ID_1",
"name": "Product 1"
},
{
"id": "PROD_ID_2",
"name": "Product 2"
}
],
"prices": [
{
"productId": "PROD_ID_1",
"type": "PRICE_TYPE_1",
"amount": "1.0"
},
{
"productId": "PROD_ID_2",
"type": "PRICE_TYPE_2",
"amount": "2.0"
},
{
"productId": "PROD_ID_1",
"type": "PRICE_TYPE_3",
"amount": "3.0"
},
{
"productId": "PROD_ID_3",
"type": "PRICE_TYPE_4",
"amount": "4.0"
}
]
}
Expected output:
{
"products": [
{
"id": "PROD_ID_1",
"name": "Product 1",
"prices": [
{
"productId": "PROD_ID_1",
"type": "PRICE_TYPE_1",
"amount": "1.0"
},
{
"productId": "PROD_ID_1",
"type": "PRICE_TYPE_3",
"amount": "3.0"
}
]
},
{
"id": "PROD_ID_2",
"name": "Product 2",
"prices": [
{
"productId": "PROD_ID_2",
"type": "PRICE_TYPE_2",
"amount": "2.0"
}
]
}
]
}
My Jolt spec:
[
// copy all prices to every product
{
"operation": "shift",
"spec": {
"products": {
"*": {
"*": "products[&1].&",
"@(2,prices)": "products[&1].prices"
}
}
}
},
// remove prices where product.id != price.productId
{
"operation": "shift",
"spec": {
"products": {
"*": { // iterate products array
"*": "products[&1].&", // copy everything except prices
"prices": {
"*": { // iterate prices array
"productId": { // value matching --- // copy only matching objects
"PROD_ID_1": { // value <-| // FIXME: should be product.id
"@(2)": "products[&5].prices[&3]"
}
}
}
}
}
}
}
}
// TODO remove null objects from prices arrays
// TODO remove price.productId as it's redundant at this point
]
The output of my Jolt spec:
{
"products" : [ {
"prices" : [ {
"productId" : "PROD_ID_1",
"type" : "PRICE_TYPE_1",
"amount" : "1.0"
}, null, {
"productId" : "PROD_ID_1",
"type" : "PRICE_TYPE_3",
"amount" : "3.0"
} ],
"id" : "PROD_ID_1",
"name" : "Product 1"
}, {
"prices" : [ {
"productId" : "PROD_ID_1",
"type" : "PRICE_TYPE_1",
"amount" : "1.0"
}, null, {
"productId" : "PROD_ID_1",
"type" : "PRICE_TYPE_3",
"amount" : "3.0"
} ],
"id" : "PROD_ID_2",
"name" : "Product 2"
} ]
}
英文:
I have two top level arrays: products
and prices
. I have to move all those price
objects under product
where price.productId == product.id
. Note that there can be any number of products
and prices
and their relationships.
My current solution:
- copies all prices to every product
- tries to "remove" all those prices where ids don't match
The problem is I can't figure out how to match to the value of product.id
in the step #2. In my example below I have hardcoded the value, see the FIXME
comment.
I'm also open for better solutions if any.
Note also two TODO extra points (that might vanish with a more appropriate solution).
This is a simplified version of the actual problem to illustrate the point.
Input:
{
"products": [
{
"id": "PROD_ID_1",
"name": "Product 1"
},
{
"id": "PROD_ID_2",
"name": "Product 2"
}
],
"prices": [
{
"productId": "PROD_ID_1",
"type": "PRICE_TYPE_1",
"amount": "1.0"
},
{
"productId": "PROD_ID_2",
"type": "PRICE_TYPE_2",
"amount": "2.0"
},
{
"productId": "PROD_ID_1",
"type": "PRICE_TYPE_3",
"amount": "3.0"
},
{
"productId": "PROD_ID_3",
"type": "PRICE_TYPE_4",
"amount": "4.0"
}
]
}
Expected output:
{
"products": [
{
"id": "PROD_ID_1",
"name": "Product 1",
"prices": [
{
"productId": "PROD_ID_1",
"type": "PRICE_TYPE_1",
"amount": "1.0"
},
{
"productId": "PROD_ID_1",
"type": "PRICE_TYPE_3",
"amount": "3.0"
}
]
},
{
"id": "PROD_ID_2",
"name": "Product 2",
"prices": [
{
"productId": "PROD_ID_2",
"type": "PRICE_TYPE_2",
"amount": "2.0"
}
]
}
]
}
My Jolt spec:
[
// copy all prices to every product
{
"operation": "shift",
"spec": {
"products": {
"*": {
"*": "products[&1].&",
"@(2,prices)": "products[&1].prices"
}
}
}
},
// remove prices where product.id != price.productId
{
"operation": "shift",
"spec": {
"products": {
"*": { // iterate products array
"*": "products[&1].&", // copy everything except prices
"prices": {
"*": { // iterate prices array
"productId": { // value matching --- // copy only matching objects
"PROD_ID_1": { // value <-| // FIXME: should be product.id
"@(2)": "products[&5].prices[&3]"
}
}
}
}
}
}
}
}
// TODO remove null objects from prices arrays
// TODO remove price.productId as it's redundant at this point
]
The output of my Jolt spec:
{
"products" : [ {
"prices" : [ {
"productId" : "PROD_ID_1",
"type" : "PRICE_TYPE_1",
"amount" : "1.0"
}, null, {
"productId" : "PROD_ID_1",
"type" : "PRICE_TYPE_3",
"amount" : "3.0"
} ],
"id" : "PROD_ID_1",
"name" : "Product 1"
}, {
"prices" : [ {
"productId" : "PROD_ID_1",
"type" : "PRICE_TYPE_1",
"amount" : "1.0"
}, null, {
"productId" : "PROD_ID_1",
"type" : "PRICE_TYPE_3",
"amount" : "3.0"
} ],
"id" : "PROD_ID_2",
"name" : "Product 2"
} ]
}
答案1
得分: 1
你可以使用这个规范:
[
{
"operation": "shift",
"spec": {
"products": {
"*": {
"@": "&2.@(1,id)"
}
},
"prices": {
"*": {
"@": "&2.@(1,productId)"
}
}
}
},
{
"operation": "shift",
"spec": {
"products": {
"*": {
"*": "&2.&1.&",
"@(3,prices.&)": "&2.&1.prices"
}
}
}
},
{
"operation": "cardinality",
"spec": {
"*": {
"*": {
"prices": "MANY"
}
}
}
},
{
"operation": "shift",
"spec": {
"*": {
"*": {
"@": "&2[]"
}
}
}
}
]
注意:上述代码已经将HTML实体编码的字符解码为正常的JSON格式。
英文:
You can use this spec:
[
{
"operation": "shift",
"spec": {
"products": {
"*": {
"@": "&2.@(1,id)"
}
},
"prices": {
"*": {
"@": "&2.@(1,productId)"
}
}
}
},
{
"operation": "shift",
"spec": {
"products": {
"*": {
"*": "&2.&1.&",
"@(3,prices.&)": "&2.&1.prices"
}
}
}
},
{
"operation": "cardinality",
"spec": {
"*": {
"*": {
"prices": "MANY"
}
}
}
},
{
"operation": "shift",
"spec": {
"*": {
"*": {
"@": "&2[]"
}
}
}
}
]
答案2
得分: 1
以下是翻译好的部分:
你可以使用以下规范
[
{// 累积匹配的 id 值("products.id" vs. "prices.productId")
// 在由这些 id 值标记的公共节点下
"operation": "shift",
"spec": {
"prices": {
"*": {
"productId": {
"*": { // 返回 "prices" 数组
"@2": "&.4[]"
},
"@(3,products[&1])": "@0" // 返回 "id" & "name" 属性
}
}
}
}
},
{ // 仅提取具有 "id" 属性的对象
"operation": "shift",
"spec": {
"*": {
"id": {
"@1": "products[]"
}
}
}
}
]
在网站 http://jolt-demo.appspot.com/ 上的 演示 如下图所示
英文:
You can use the following spec
[
{// acuumulate the matching id values ( "products.id" vs. "prices.productId" )
// under common nodes tagged by those id values
"operation": "shift",
"spec": {
"prices": {
"*": {
"productId": {
"*": { // returns "prices" array
"@2": "&.&4[]"
},
"@(3,products[&1])": "@0" // returns "id" & "name" attributes
}
}
}
}
},
{ // pick objects up only having "id" attribute
"operation": "shift",
"spec": {
"*": {
"id": {
"@1": "products[]"
}
}
}
}
]
the demo on the site http://jolt-demo.appspot.com/ is
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论