JSON Get parent object from child object

匿名 (未验证) 提交于 2019-12-03 01:38:01

问题:

How can I get discount value if brand_id=='983'.

Sample JSON:

{      "prods": [                {             "info": {                   "rate": 100                     },             "grocery": [                      {                       "brand": "A",                       "brand_id": "983"                      },                      {                       "brand": "B",                       "brand_id": "253"                      }                      ],              "discount": "20"          }      ] } 

What I have tried till now is

$.prods[*].grocery[?(@.brand_id=='983')] 

This returns me list/array of matched objects. But I am not able to traverse back into the tree. Any help on this?

回答1:

Indeed, JSONPath isn't very good at that, so I tackled this kind of problem with my own small library; so, here's a fiddle for your example:

https://jsfiddle.net/YSharpLanguage/j9oetwnn/3

where:

var products = {      "prods": [         {             "info": {                   "rate": 85                     },             "grocery": [                      {                       "brand": "C",                       "brand_id": "984"                      },                      {                       "brand": "D",                       "brand_id": "254"                      }                      ],              "discount": "15"         },         {             "info": {                   "rate": 100                     },             "grocery": [                      {                       "brand": "A",                       "brand_id": "983"                      },                      {                       "brand": "B",                       "brand_id": "253"                      }                      ],              "discount": "20"          }      ] };  function GroceryItem(obj) {   return (typeof obj.brand === "string") && (typeof obj.brand_id === "string"); }      // last parameter set to "true", to grab all the "GroceryItem" instances     // at any depth: var itemsAndDiscounts = [ products ].nodeset(GroceryItem, true).     map(       function(node) {         var item = node.value, // node.value: the current "GroceryItem" (aka "$.prods[*].grocery[*]")              discount = node.parent. // node.parent: the array of "GroceryItem" (aka "$.prods[*].grocery")                        parent. // node.parent.parent: the product (aka "$.prods[*]")                        discount; // node.parent.parent.discount: the product discount          // finally, project into an easy-to-filter form:         return { id: item.brand_id, discount: discount };       }     ),     discountOfItem983;  discountOfItem983 = itemsAndDiscounts.   filter   (     function(mapped) {       return mapped.id === "983";     }   )   [0].discount;  console.log("All items and discounts: " + JSON.stringify(itemsAndDiscounts, null, 2));  console.log("Discount of #983: " + discountOfItem983); 

gives:

All items and discounts: [   {     "id": "984",     "discount": "15"   },   {     "id": "254",     "discount": "15"   },   {     "id": "983",     "discount": "20"   },   {     "id": "253",     "discount": "20"   } ] Discount of #983: 20 

Here are other examples / use cases:

JSON-to-some-markup

JSON transformations, revisited (XSLT look-alike)

(at: https://jsfiddle.net/YSharpLanguage/kj9pk8oz/10)

JSON-to-JSON

Super-lightweight JSON-to-JSON transformations

(at: https://jsfiddle.net/YSharpLanguage/ppfmmu15/10)

A JavaScript equivalent of...

XSLT 3.0 REC Section 14.4 Example: Grouping Nodes based on Common Values

(at: http://jsfiddle.net/YSharpLanguage/8bqcd0ey/1)

Cf. https://www.w3.org/TR/xslt-30/#grouping-examples

A JavaScript equivalent of...

JSONiq Use Cases Section 1.1.2. Grouping Queries for JSON

(at: https://jsfiddle.net/YSharpLanguage/hvo24hmk/3)

Cf. http://jsoniq.org/docs/JSONiq-usecases/html-single/index.html#jsongrouping

'Hope this helps,



回答2:

You can write a function that returns the parent node. Once you have that, you should develop a function that walks (traverses) all the object and all its nodes and arrays, and when it finds the desired Id, well, you just get the parent and retrieve for the discount.

Here you have the simplest example of a function that returns the parent node:

const myVar = {   "prods": [{     "info": {       "rate": 100     },     "grocery": [{         "brand": "A",         "brand_id": "983",         myParent: function() {           const that = this; // to fix the caller instead of using 'bind' or 'apply'           return that;         }       },       {         "brand": "B",         "brand_id": "253",         myParent: function() {           const that = this;           return that;         }       }     ],     "discount": "20"   }] } function myFunction() {     let x = document.getElementById("myNumber").value;     let text = myVar.prods[0].grocery.find(el => el.brand_id === x).myParent().brand;      document.getElementById("demo").innerHTML = text; }
<input type="number" id="myNumber" value="253"> <button onclick="myFunction()">Try it</button> <p id="demo"></p>


标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!