2017-07-28 7 views
0

Je voudrais pouvoir utiliser jq pour sortir le 'produit' de 2 tableaux dans l'entrée JSON ... par exemple, étant donné JSON d'entrée suivante:Comment utiliser jq pour produire un produit cartésien de deux tableaux présents dans l'entrée JSON

{ 
    "quantities": [ 
     { 
      "product": "A", 
      "quantity": 30 
     }, 
     { 
      "product": "B", 
      "quantity": 10 
     } 
     ], 
    "portions": [ 
     { 
      "customer": "C1", 
      "percentage": .6 
     }, 
     { 
      "customer": "C2", 
      "percentage": .4 
     } 
    ] 
} 

Je voudrais produire la sortie suivante (ou similaire ...):

[ 
    { 
    "customer": "C1", 
    "quantities": [ 
     { 
      "product": "A", 
      "quantity": 18 
     }, 
     { 
      "product": "B", 
      "quantity": 6 
     } 
     ] 
    }, 
    { 
    "customer": "C2", 
    "quantities": [ 
     { 
      "product": "A", 
      "quantity": 12 
     }, 
     { 
      "product": "B", 
      "quantity": 4 
     } 
     ] 
    } 
] 

en d'autres termes, pour chaque partie, utiliser la valeur du pourcentage et l'appliquer à chaque quantité de produit. Compte tenu des quantités 2 et 2 parties devraient donner des résultats 4 .. donné 3 quantités et 2 parties devraient donner 6 résultats, etc ...

J'ai fait quelques tentatives en utilisant les filtres foreach, mais en vain ...

Répondre

0

Je pense que cela fera ce que vous voulez.

[ 
    .quantities as $q 
| .portions[] 
| .percentage as $p 
| { 
    customer, 
    quantities: [ 
     $q[] | .quantity = .quantity * $p 
    ] 
    } 
] 
0

Puisque vous avez indiqué que vous voulez que le produit cartésien, et que vous ne avez donné l'exemple de sortie comme étant une indication de ce que vous cherchez, il peut être utile de mentionner que l'on peut obtenir très simplement le produit cartésien:

.portions[] + .quantities[] 

Ce produit des objets tels que:

{ 
    "product": "B", 
    "quantity": 10, 
    "customer": "C2", 
    "percentage": 0.4 
} 

Vous pouvez ensuite utiliser reduce ou (moins efficace, group_by) à obtenir les données sous la forme que vous voulez vraiment.

Par exemple, en supposant .customer est toujours une chaîne, nous pourrions transformer l'entrée dans le format requis comme suit:

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 })