मैं एक ऐसा फ़ंक्शन लिखना चाहता हूं जो नेस्टेड जेसन ऑब्जेक्ट लेता है और प्रत्येक ऑब्जेक्ट में एक path सरणी लिखता है जो ऑब्जेक्ट के "पथ" या पदानुक्रम को दर्शाता है। path सरणी को पैरेंट नोड्स के id द्वारा पॉप्युलेट किया जाना चाहिए। सीमा सरणी वस्तुओं में पथ होना चाहिए और चूंकि उनके पास कोई आईडी नहीं है, इसलिए उस सरणी में अनुक्रमणिका के आधार पर उन्हें एक गणना की गई कुंजी दी जाती है। मेरा प्रयास नीचे है हालांकि मुझे कुछ निश्चित nth स्तरों पर सही रास्ता नहीं मिल रहा है।

let nestedObject = {
    "name":"bob",
    "root_rule":{
       "id":0,
       "limits":[
          {
             "value":0
          }
       ],
       "rules":[
          {
             "id":15,
             "limits":[
                
             ],
             "rules":[
                
             ]
          },
          {
             "id":16,
             "limits":[
                {
                   "value":25000000
                },
                {
                   "value":50001
                },
                {
                   "value":25000001
                }
             ],
             "rules":[
                {
                   "id":20,
                   "limits":[
                      {
                         "value":0
                      }
                   ],
                   "rules":[
                      {
                         "id":21,
                         "limits":[
                            
                         ],
                         "rules":[
                            
                         ]
                      }
                   ]
                }
             ]
          }
       ]
    }
 }
function encodeNestedPath(nestedJson, pathList, type, parent = null) {

    // process rood node
    if ((typeof nestedJson) == 'object') {
        
        if(nestedJson && nestedJson.condition && nestedJson.condition.name === 'ROOT') {
            nestedJson['path'] = [String(nestedJson['id'])];
        }
        
        if(nestedJson.limits) {
            encodeNestedPath(nestedJson.limits, nestedJson['path'], 'limits', nestedJson['id']);
        }
        if(nestedJson.rules) {
            encodeNestedPath(nestedJson.rules, nestedJson['path'], 'rules', nestedJson['id']);
        }
    }

    // traverse children nodes
    if (Array.isArray(nestedJson)) {
        for (const [i, element] of nestedJson.entries()) {

            element['path'] = [];

            if(String(parent)) {
                element['path'].push(String(parent))
            }

            let parentId
            if(!element.hasOwnProperty('id')) {
                element['path'].push(type+'_'+i)
                pathList = null
            } else {
                element['path'].push(String(element['id']))
                parentId = element['id']
            }

            if(element.limits) {
                encodeNestedPath(element.limits, element['path'], 'limits', parentId);
            }
            if(element.rules) {
                encodeNestedPath(element.rules, element['path'], 'rules', parentId);
            }
        }
    }
}



encodeNestedPath(nestedObject['root_rule'], null, null, null)
console.log(JSON.stringify(nestedObject['root_rule'], null, 4))

वांछित उत्पादन इस प्रकार है। इमेज ऑफ इवांटेड आउटपुट

0
stackoverlflowAdmin 24 अक्टूबर 2020, 09:38

2 जवाब

सबसे बढ़िया उत्तर

आपके फ़ंक्शन में एक समस्या यह है कि आप pathList तर्क के साथ कुछ भी उपयोगी नहीं करते हैं। इसके बजाय, आप स्क्रैच से पथ बनाना शुरू करते हैं:

nestedJson['path'] = [String(nestedJson['id'])];

और साथ:

element['path'] = [];

जहां बाद वाले को एक ही धक्का दिया जाता है।

संक्षेप में आपके सभी path गुण लंबाई 1 के सरणियों पर सेट हैं।

यहां एक कार्यान्वयन है जो ऑब्जेक्ट पदानुक्रम के माध्यम से पुनरावृत्त करता है (हार्डकोडेड गुणों जैसे limits या rules के लिए विशेष उपचार के बिना) और आपके द्वारा वर्णित तर्क को लागू करता है:

function encodeNestedPath(obj, pathList=[], parentKey) {
    if (Array.isArray(obj)) {
         // remove plural and append underscore
        parentKey = parentKey !== undefined ? parentKey.replace(/s?$/, "_") : "";
        obj.forEach((elem, i) => encodeNestedPath(elem, pathList, parentKey + i));
    } else if (Object(obj) === obj) {
        if ("id" in obj) parentKey = obj.id;
        if (parentKey !== undefined) pathList = pathList.concat(parentKey);
        if (pathList.length) obj.path = pathList
        for (let prop in obj) encodeNestedPath(obj[prop], pathList, prop);
    }
}

// object from the question:
let nestedObject = {"name": "bob","root_rule":{"id":0,"limits":[{"value":0}],"rules":[{"id":15,"limits":[],"rules":[]},{"id":16,"limits":[{"value":25000000},{"value":50001},{"value":25000001}],"rules":[{"id":20,"limits":[{"value":0}],"rules":[{"id":21,"limits":[],"rules":[]}]}]}]}};

encodeNestedPath(nestedObject);
console.log(nestedObject);
1
trincot 24 अक्टूबर 2020, 12:59

पहिया को फिर से शुरू करने का बहुत बड़ा प्रशंसक नहीं है। मैं अनुशंसा करता हूं कि आप मूल बातें के लिए पुस्तकालय का उपयोग करें। हम इन दिनों अपने सभी डेटा प्रोसेसिंग के लिए ऑब्जेक्ट-स्कैन का उपयोग करते हैं। एक बार जब आप इसका उपयोग करने के तरीके के बारे में अपना सिर लपेट लेते हैं तो यह शक्तिशाली होता है। यहां बताया गया है कि आप अपने प्रश्नों को हल करने के लिए इसका उपयोग कैसे करेंगे:

// const objectScan = require('object-scan');

const process = (data) => objectScan(['**.id', '**.limits[*]'], {
  rtn: 'bool',
  filterFn: ({ value, parents, property }) => {
    const path = parents.filter((p) => 'id' in p).map(({ id }) => id).reverse();
    if (property === 'id') {
      parents[0].path = path;
    } else {
      value.path = path.concat(`limit_${property}`);
    }
  }
})(data);

const data = { name: 'bob', root_rule: { id: 0, limits: [{ value: 0 }], rules: [{ id: 15, limits: [], rules: [] }, { id: 16, limits: [{ value: 25000000 }, { value: 50001 }, { value: 25000001 }], rules: [{ id: 20, limits: [{ value: 0 }], rules: [{ id: 21, limits: [], rules: [] }] }] }] } };

console.log(process(data)); // returns true iff match
// => true

console.log(data);
// => { name: 'bob', root_rule: { id: 0, limits: [ { value: 0, path: [ 0, 'limit_0' ] } ], rules: [ { id: 15, limits: [], rules: [], path: [ 0, 15 ] }, { id: 16, limits: [ { value: 25000000, path: [ 0, 16, 'limit_0' ] }, { value: 50001, path: [ 0, 16, 'limit_1' ] }, { value: 25000001, path: [ 0, 16, 'limit_2' ] } ], rules: [ { id: 20, limits: [ { value: 0, path: [ 0, 16, 20, 'limit_0' ] } ], rules: [ { id: 21, limits: [], rules: [], path: [ 0, 16, 20, 21 ] } ], path: [ 0, 16, 20 ] } ], path: [ 0, 16 ] } ], path: [ 0 ] } }
.as-console-wrapper {max-height: 100% !important; top: 0}
<script src="https://bundle.run/object-scan@13.8.0"></script>

अस्वीकरण: मैं ऑब्जेक्ट-स्कैन का लेखक हूं

वैकल्पिक तरीका जो आपको अधिक नियंत्रण देता है

// const objectScan = require('object-scan');

const process = (data) => {
  const extractPath = (parents) => parents
    .filter((p) => 'id' in p)
    .map(({ id }) => id)
    .reverse();
  const logic = {
    '**.id': ({ parents }) => {
      parents[0].path = extractPath(parents);
    },
    '**.limits[*]': ({ value, parents, property }) => {
      value.path = [...extractPath(parents), `limit_${property}`];
    }
  };
  return objectScan(Object.keys(logic), {
    rtn: 'bool',
    filterFn: (kwargs) => kwargs.traversedBy.forEach((n) => logic[n](kwargs))
  })(data);
};

const data = { name: 'bob', root_rule: { id: 0, limits: [{ value: 0 }], rules: [{ id: 15, limits: [], rules: [] }, { id: 16, limits: [{ value: 25000000 }, { value: 50001 }, { value: 25000001 }], rules: [{ id: 20, limits: [{ value: 0 }], rules: [{ id: 21, limits: [], rules: [] }] }] }] } };

console.log(process(data));
// => true

console.log(data);
// => { name: 'bob', root_rule: { id: 0, limits: [ { value: 0, path: [ 0, 'limit_0' ] }, path: [ 0 ] ], rules: [ { id: 15, limits: [], rules: [], path: [ 0, 15 ] }, { id: 16, limits: [ { value: 25000000, path: [ 0, 16, 'limit_0' ] }, { value: 50001, path: [ 0, 16, 'limit_1' ] }, { value: 25000001, path: [ 0, 16, 'limit_2' ] }, path: [ 0, 16 ] ], rules: [ { id: 20, limits: [ { value: 0, path: [ 0, 16, 20, 'limit_0' ] }, path: [ 0, 16, 20 ] ], rules: [ { id: 21, limits: [], rules: [], path: [ 0, 16, 20, 21 ] } ], path: [ 0, 16, 20 ] } ], path: [ 0, 16 ] } ], path: [ 0 ] } }
.as-console-wrapper {max-height: 100% !important; top: 0}
<script src="https://bundle.run/object-scan@13.8.0"></script>

अस्वीकरण: मैं ऑब्जेक्ट-स्कैन का लेखक हूं

0
vincent 17 जिंदा 2021, 08:50