2016-04-06 10 views
6

मैं नीचे प्रारूप में वस्तुओं की एक सरणी है। मुझे जेसन ऑब्जेक्ट के माध्यम से पुनरावृत्त करने की आवश्यकता है और रूट्स तक name खाली स्ट्रिंग है जो सभी नोड्स को हटा दें। ऊपर json प्रारूप के लिए, उत्पादन नीचे की तरह होना चाहिए:रिकर्सिवली सरणी वस्तु संघनक जावास्क्रिप्ट में

{ 
    "country": "India", 
    "children": [ 
    { 
     "name": "Karnataka", 
     "type": "State", 
     "children": [ 
     { 
      "name": "Bangalore", 
      "type": "city" 
     }, 
     { 
      "name": "Mangalore", 
      "type": "city" 
     } 
     ] 
    }, 
    { 
     "name": "Kerala", 
     "type": "State", 
     "children": [ 
     ] 
    }, 
    { 
     "name": "Maharastra", 
     "type": "State", 
     "children": [ 
     { 
      "name": "Mumbai", 
      "type": "city" 
     }, 
     { 
      "name": "Pune", 
      "type": "city" 
     } 
     ] 
    } 
    ] 
} 

जावास्क्रिप्ट में यह करने के लिए कैसे Underscorejs का उपयोग कर रिकर्सिवली।

+0

'ऐरे # मानचित्र' ..? – Rayon

+0

@ RayonDabre- मुझे लगता है * lowRight * और अवांछित सदस्यों को हटाएं बेहतर है, लेकिन underscore.js क्या है? यदि कोई अंतर्निहित नहीं है। – RobG

+0

[यह SO सवाल] (http://stackoverflow.com/questions/36171667/find-and-remove-empty-properties-from-objects/36171824) आपकी मदद कर सकता है – Aides

उत्तर

3

यह एक पुनरावर्ती है Array#filter() के साथ समाधान।

function filterName(a) { 
 
    if (a.name) { 
 
     if (Array.isArray(a.children)) { 
 
      a.children = a.children.filter(filterName); 
 
     } 
 
     return true; 
 
    } 
 
} 
 

 
var object = { "country": "India", "children": [{ "name": "Karnataka", "type": "State", "children": [{ "name": "", "type": "city" }, { "name": "Bangalore", "type": "city" }, { "name": "Mangalore", "type": "city" }] }, { "name": "Kerala", "type": "State", "children": [{ "name": "", "type": "city" }] }, { "name": "Maharashtra", "type": "State", "children": [{ "name": "Mumbai", "type": "city" }, { "name": "Pune", "type": "city" }] }] }; 
 

 
object.children.forEach(filterName); 
 
document.write("<pre>" + JSON.stringify(object, 0, 4) + "</pre>");

1

इस प्रयास करें:

function condense(arr) { 

    arr.children = arr.children.map(function(c) { 
    c.children = c.children.filter(function(c1) { 
     return c1.name; 
    }); 
    return c; 
    }); 

    return arr; 
} 

मैं बच्चों के माध्यम से पुनरावृति (map साथ), तो filter के साथ बच्चों सरणी फ़िल्टर करें। केवल नाम वाले बच्चे नल या खाली नहीं होंगे।

यहां एक jsfiddle है।

+0

मैंने समान दृष्टिकोण की कोशिश की। मैं इसे रिकर्सन के साथ प्रयास करना चाहता था। – zilcuanu

+0

क्यों? आपके पास केवल दो गहराई का स्तर है। इसके अलावा, पहले स्तर पर, आप खाली बच्चों को दूसरे स्थान पर हटाते हैं। यह एक अच्छा रिकर्सन उम्मीदवार की तरह प्रतीत नहीं होता है। – Derlin

1

au fait underscore.js के साथ। आप इसे ईएस 5 कम करने के साथ कर सकते हैं राइट और उन सदस्यों को हटाएं जिन्हें आप नहीं चाहते हैं, यह अन्य दृष्टिकोणों की तुलना में अधिक कुशल होना चाहिए। निम्नलिखित प्रत्यावर्तन (जो धारावाहिक प्रसंस्करण के रूप में के रूप में कुशल नहीं है, लेकिन संभावना कम कोड है) का उपयोग करता है, तो आप घोंसला वस्तुओं के रूप में गहरी के रूप में आप की तरह कर सकते हैं:

function removeEmpty(obj) { 
 
    obj.children.reduceRight(function (acc, child, i) { 
 
    if (!child.name) { 
 
     obj.children.splice(i, 1); 
 
    } else if (child.children) { 
 
     removeEmpty(child); 
 
    } 
 
    return null; 
 
    }, null); 
 
    return obj; 
 
} 
 

 
// Test 
 
var data = { 
 
    "country": "India", 
 
    "children": [ 
 
    { 
 
     "name": "Karnataka", 
 
     "type": "State", 
 
     "children": [ 
 
     { 
 
      "name": "", 
 
      "type": "city" 
 
     }, 
 
     { 
 
      "name": "Bangalore", 
 
      "type": "city" 
 
     }, 
 
     { 
 
      "name": "Mangalore", 
 
      "type": "city" 
 
     } 
 
     ] 
 
    }, 
 
    { 
 
     "name": "Kerala", 
 
     "type": "State", 
 
     "children": [ 
 
     { 
 
      "name": "", 
 
      "type": "city" 
 
     } 
 
     ] 
 
    }, 
 
    { 
 
     "name": "Maharashtra", 
 
     "type": "State", 
 
     "children": [ 
 
     { 
 
      "name": "Mumbai", 
 
      "type": "city" 
 
     }, 
 
     { 
 
      "name": "Pune", 
 
      "type": "city" 
 
     } 
 
     ] 
 
    } 
 
    ] 
 
} 
 

 

 
document.write('Original:<br>' + JSON.stringify(data) + '<br><br>' + 
 
       'Modified:<br>' + JSON.stringify(removeEmpty(data)));

+0

ओह, 'lowRight' का उपयोग यहां इतना भ्रमित है, क्योंकि आप कुछ भी कम नहीं कर रहे हैं ... – Bergi

+0

हां, यह लंबाई से 0 तक फिर से शुरू हो रहा है, जमाकर्ता को अनदेखा किया जाता है। शायद एक * forEachRight * होना चाहिए? ;-) अब इसके बारे में सोचते हुए, * वापसी शून्य * छोड़ा जा सकता है। – RobG

+0

शायद 'acc' के बजाय '_' भी हो सकता है – Bergi

1

यह आपके उदाहरण के लिए बहुत विशिष्ट है।

Link to fiddle

var obj = { 
 
    "country": "India", 
 
    "children": [{ 
 
    "name": "Karnataka", 
 
    "type": "State", 
 
    "children": [{ 
 
     "name": "", 
 
     "type": "city" 
 
    }, { 
 
     "name": "Bangalore", 
 
     "type": "city" 
 
    }, { 
 
     "name": "Mangalore", 
 
     "type": "city" 
 
    }] 
 
    }, { 
 
    "name": "Kerala", 
 
    "type": "State", 
 
    "children": [{ 
 
     "name": "", 
 
     "type": "city" 
 
    }] 
 
    }, { 
 
    "name": "Maharashtra", 
 
    "type": "State", 
 
    "children": [{ 
 
     "name": "Mumbai", 
 
     "type": "city" 
 
    }, { 
 
     "name": "Pune", 
 
     "type": "city" 
 
    }] 
 
    }] 
 
}; 
 

 
//Before 
 
document.write("BEFORE: "+JSON.stringify(obj)); 
 
//After 
 
document.write("AFTER: "+JSON.stringify(checkJSON(obj))); 
 

 
function checkJSON(obj) { 
 
    $.each(obj.children, function(index, value) { 
 
    if ($.isArray(value.children)) { 
 
     $.each(value.children, function(index, value) { 
 
     if (value.name == '') { 
 
      delete value.name; 
 
     } 
 
     }); 
 
    } 
 
    }); 
 
    return obj; 
 
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>

1

शायद नहीं सबसे छोटा रास्ता है, लेकिन यह काम करता है:

obj.children = _.each(obj.children, filter); 

function filter(child, index, arr) { 
    if (child && child.name === '') { 
    // remove the ones without name 
    arr.splice(index, 1); 

    } else if (_.has(child, 'children')) { 
    // remove nested children 
    child.children = _.each(child.children, filter); 

    // check for empty children array and remove it (if needed) 
    /* 
    if (child.children.length === 0) { 
     delete child['children']; 
    } 
    */ 
    } 

    return child; 
} 

फिडल: https://jsfiddle.net/gnmosu5p/2/

1

मैं एक पुनरावर्ती एक पता पिप्रोच से पूछा जाता है लेकिन मैं यहां एक सिंगल लाइनर देने से खुद की मदद नहीं कर सकता।

var newData = JSON.parse(JSON.stringify(data).replace(/{"name":"".+?},?/g, "")); 

जहां data शुरू में दिए गए वस्तु है पुनर्गठन किया जाना है।

यह सरणी कार्यों की तुलना में कुछ हद तक धीमा है लेकिन इस विधि का एक लाभ मूल डेटा ऑब्जेक्ट को संरक्षित करना है, जबकि यह सभी सरणी विधियां मूल डेटा ऑब्जेक्ट को ओवरराइड कर देती हैं जब तक कि आप इसे क्लोन नहीं करते।

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