2011-11-10 18 views
27

मैं स्ट्रिंग द्वारा पहचाने गए विशिष्ट ऑब्जेक्ट को पुनर्प्राप्त करने के लिए नेस्टेड ऑब्जेक्ट के माध्यम से पुनरावृत्ति करने का प्रयास कर रहा हूं। नीचे नमूना वस्तु में, पहचानकर्ता स्ट्रिंग "लेबल" संपत्ति है। उचित वस्तु को वापस करने के लिए पेड़ के माध्यम से फिर से घुमाने के लिए मैं अपने सिर को लपेट नहीं सकता। किसी सहायता या सुझावों की काफी सराहना की जाएगी।नेस्टेड जावास्क्रिप्ट ऑब्जेक्ट्स के माध्यम से Iterate

var cars = 
    { 
     label: 'Autos', 
     subs: 
      [ 
       { 
        label: 'SUVs', 
        subs: [] 
       }, 
       { 
        label: 'Trucks', 
        subs: [ 
           { 
           label: '2 Wheel Drive', 
           subs: [] 
           }, 
           { 
           label: '4 Wheel Drive', 
           subs: [ 
              { 
              label: 'Ford',           
              subs: [] 
              }, 
              { 
              label: 'Chevrolet', 
              subs: []          
              } 
             ]       
           } 
          ]  
       }, 
       { 
        label: 'Sedan', 
        subs: [] 
       } 
      ] 
    } 
+1

संभावित डुप्लिकेट [जावास्क्रिप्ट के साथ एक JSON ऑब्जेक्ट ट्री के सभी नोड्स को पार करें] (http://stackoverflow.com/questions/722668/traverse-all-the-nodes-of-a-json-object-tree- जावास्क्रिप्ट के साथ) –

+0

आप किसी मनमानी लेबल के लिए ऑब्जेक्ट के सभी स्तरों के माध्यम से खोजना चाहते हैं? (आह, ट्रैवर्स, वह शब्द था जिसे मैं ढूंढ रहा था।) – Dave

+0

[एक्सेस/प्रोसेस (नेस्टेड) ​​ऑब्जेक्ट्स, एरेज़ या जेएसओएन का संभावित डुप्लिकेट] (http://stackoverflow.com/questions/11922383/access-process-nested -objects-arrays-or-json) – Liam

उत्तर

34

आप की तरह इस गहराई करने के लिए एक पुनरावर्ती क्रिया बना सकते हैं cars ऑब्जेक्ट का पहला ट्रैवर्सल।

var findObjectByLabel = function(obj, label) { 
    if(obj.label === label) { return obj; } 
    for(var i in obj) { 
     if(obj.hasOwnProperty(i)){ 
      var foundLabel = findObjectByLabel(obj[i], label); 
      if(foundLabel) { return foundLabel; } 
     } 
    } 
    return null; 
}; 

जो इतनी

findObjectByLabel(car, "Chevrolet"); 
+0

मूल पोस्ट में, उप कार कार कार ऑब्जेक्ट की गुण नहीं हैं, लेकिन 'subs' सरणी में निहित हैं। –

+0

@ जेम्सस्कार्क मुझे पता है। यह अभी भी काम करना चाहिए, और यदि यह एक से अधिक सरणी संपत्ति है तो वह लचीला है अगर वह 'subs'' का नाम किसी अन्य चीज़ में बदलने का फैसला करता है। –

+1

बहुत गहरी वस्तुओं के लिए रिकर्सन खराब है। आप ढेर अतिप्रवाह मिलेगा। –

2

निम्नलिखित कोड कोई वृत्तीय संदर्भ मान लिया गया है, और मान लिया गया subs हमेशा एक सरणी (और पत्र-गांठ में रिक्त नहीं) है:

function find(haystack, needle) { 
    if (haystack.label === needle) return haystack; 
    for (var i = 0; i < haystack.subs.length; i ++) { 
    var result = find(haystack.subs[i], needle); 
    if (result) return result; 
    } 
    return null; 
} 
2

आगे पेड़ हेरफेर के लिए प्रदर्शन बढ़ाने के लिए की तरह कहा जा सकता है लाइन संग्रह दृश्य में ट्री दृश्य को बदलने के लिए, की तरह [obj1, obj2, obj3] अच्छा है। आप माता-पिता/बच्चे के दायरे में आसानी से नेविगेट करने के लिए अभिभावक-बाल ऑब्जेक्ट संबंधों को स्टोर कर सकते हैं।

संग्रह के अंदर तत्व खोजना अधिक कुशल है तो पेड़ के अंदर तत्व ढूंढें (रिकर्सन, अतिरिक्त गतिशील कार्य निर्माण, बंद करें)।

0

पीटर ओल्सन के जवाब से संशोधित: https://stackoverflow.com/a/8085118

  1. से बच सकते हैं स्ट्रिंग मान !obj || (typeof obj === 'string'
  2. कर सकते हैं कस्टम अपने प्रमुख

var findObjectByKeyVal= function (obj, key, val) { 
    if (!obj || (typeof obj === 'string')) { 
    return null 
    } 
    if (obj[key] === val) { 
    return obj 
    } 

    for (var i in obj) { 
    if (obj.hasOwnProperty(i)) { 
     var found = findObjectByKeyVal(obj[i], key, val) 
     if (found) { 
     return found 
     } 
    } 
    } 
    return null 
} 
0

यहाँ एक मृत है बुद्धिमान विधि केवल 3 चर बुद्धि का उपयोग कर हौट रिकर्सन

function forEachNested(O, f){ 
    O = Object.values(O); 
    var cur; 
    while (O.length){ 
     cur = O.pop() 
     f(cur); 
     if (typeof cur === 'object' && cur.constructor === Object) 
      O.push.apply(O, Object.values(cur)); 
    } 
} 

आप वृत्तीय संदर्भ (जैसे होने वस्तु एक के मूल्यों वस्तु एक जैसे कि वस्तु एक ही होता है में ही किया जा रहा है) के साथ एक समस्या है, या आप बस कुंजी की जरूरत है उसके बाद निम्न धीमी समाधान उपलब्ध है।

function forEachNested(O, f){ 
    O = Object.entries(O); 
    var cur; 
    function applyToEach(x){return cur[1][x[0]] === x[1]} 
    while (O.length){ 
     cur = O.pop(); 
     f(cur[0], cur[1]); 
     if (typeof cur[1] === 'object' && cur[1].constructor === Object && 
      !O.some(applyToEach)) 
      O.push.apply(O, Object.entries(cur[1])); 
    } 
} 

इन तरीकों किसी भी तरह की किसी भी प्रत्यावर्तन का उपयोग नहीं करता के बाद से, इन कार्यों में अच्छी तरह से क्षेत्रों आप गहराई के स्तर के हजारों हो सकता है, जहां के लिए उपयुक्त हैं।

संबंधित मुद्दे