2012-06-13 14 views
6

मैं दो javascript ऑब्जेक्ट है:एक वस्तु से निकालने के मूलभूत मूल्यों

var a = { 
    x: 1, 
    y: { 
     faz: 'hello', 
     baz: '' 
    }, 
    z: [1, 2] 
}; 


var defaults = { 
    x: 2, 
    y: { 
     faz: '', 
     baz: '' 
    }, 
    z: [1, 2] 
}; 

मैं केवल कि डिफ़ॉल्ट से अलग हैं a के क्षेत्र रखना चाहते हैं:

a = remove_defaults(a, defaults); // <---- i need this fnc 
{ 
    x: 1, 
    y: { 
     faz: 'hello' 
    } 
} 

लक्ष्य है किसी ऑब्जेक्ट से डिफ़ॉल्ट मानों को निकालने के लिए जो एक राज्य (यूआरएल के माध्यम से) के रूप में कार्य करता है। राज्य में घोंसले वाले खेतों हो सकते हैं, इसलिए एक उथली तुलना पर्याप्त नहीं है। पत्ती के मूल्य सभी आदिम (संख्या, स्ट्रिंग, बूल) हैं।

सबसे अच्छा तरीका है इस लक्ष्य को हासिल करने के लिए क्या है (इस underscore.js के _.defaults() विधि के विपरीत की तरह एक सा है)?


समाधान underscore.js उपयोग कर सकते हैं कि अगर मदद करता है, लेकिन कोई jquery

+1

गुणों पर पुन: प्रयास करें और उनके मूल्यों की तुलना करें। कोई अंतर्निहित विधि नहीं है। –

उत्तर

3

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

function removeDuplicates(a, defaults, result) { 
    for (var i in a) { 
    if (i in defaults) { 
     if (typeof a[i] == "object" 
      && typeof defaults[i] == "object" 
      && Object.prototype.toString.call(defaults[i]) !== '[object Array]') { 
     result[i] = removeDuplicates(a[i], defaults[i], {}); 
     } else if (a[i] !== defaults[i]) { 
     result[i] = a[i]; 
     } 
    } else { 
     result[i] = a[i]; 
    } 
    } 

    return result; 
} 


var result = removeDuplicates(a, defaults, {}); 
+1

चीयर्स! लेकिन 'ए [i] &&' भाग क्या है? इससे सबकुछ झूठा होगा, जैसे 'झूठी', '0', '' '', 'अपरिभाषित', जो एक बग की तरह दिखता है? – user124114

+1

आप सही हैं, मैंने कोड तय किया है। – ioseb

+0

ओह, मुझे अभी एहसास हुआ कि वहां एक बड़ी बग है - सभी कॉपी किए गए फ़ील्ड अपने परिणामस्वरूप उप-क्षेत्रों में 'परिणाम' के वैश्विक दायरे में जाते हैं! – user124114

1
function remove_defaults(obj, defaults) { 
    for (var i in obj) { 
    if (typeof obj[i] == 'object') { 
     obj[i] = remove_defaults(obj[i], defaults[i]); 
     continue; 
    } 
    if (defaults[i] !== undefined && obj[i] == defaults[i]) { 
     delete obj[i]; 
    } 
    } 
    return obj; 
} 

फिडल: http://jsfiddle.net/ybVGq/

+0

यह परिणाम में 'z' सरणी छोड़ देता है। मुझे लगता है कि @ ioseb का समाधान बेहतर है, क्योंकि जब वे पूरी तरह खाली होते हैं तो वे नेस्टेड ऑब्जेक्ट्स को हटा देते हैं (= सभी आंतरिक मान डिफ़ॉल्ट के बराबर होते हैं)। – user124114

+0

हाँ, मैंने देखा कि। ऐसा इसलिए है क्योंकि मैं एक पूरी नई सरणी बनाने के बजाय 'हटाएं' का उपयोग कर रहा था। – jeremyharris

0

मेरा अपना ले:

function no_defaults(obj, defaults) { 
    if ((obj instanceof Array) && (defaults instanceof Array)) { 
     var result = _.difference(obj, defaults); 
     return _.isEmpty(result) ? undefined : result; 
    } 
    if ((obj instanceof Array) || (defaults instanceof Array)) 
     return _.clone(obj); 
    if (typeof obj == "object" && typeof defaults == "object") { 
     var result = {}; 
     for (var prop in obj) { 
      var res = prop in defaults ? no_defaults(obj[prop], defaults[prop]) : _.clone(obj[prop]); 
      if (res !== undefined) 
       result[prop] = res; 
     } 
     return _.isEmpty(result) ? undefined : result; 
    } 
    return _.isEqual(obj, defaults) ? undefined : _.clone(obj); 
} 

नोट इस गहरे प्रक्रियाओं वस्तुओं, लेकिन नहीं सरणियों। Arrays केवल उनके प्रत्यक्ष तत्वों के उथले अंतर के लिए संसाधित होते हैं - यदि तत्वों को स्वयं no_default आईएनजी की आवश्यकता है, तो यह कार्य नहीं करेगा। लेकिन यह मेरे इच्छित उपयोग के मामले के लिए ठीक है।

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