2013-01-11 10 views
10

चलिए मेरे पास अगली जावास्क्रिप्ट ऑब्जेक्ट है। अब मैं इसे क्लोन करना चाहता हूं लेकिन कुछ क्षेत्रों के बिना। उदाहरण के लिए मैं क्षेत्र "lastName" और "cars.age"
इनपुट के बिना वस्तु क्लोन चाहतेकुछ फ़ील्ड के बिना दीप क्लोन

{ 
    "firstName":"Fred", 
    "lastName":"McDonald", 
     "cars":[ 
      { 
       "type":"mersedes", 
       "age":5 
      }, 
      { 
       "model":"bmw", 
       "age":10 
      } 
     ] 
} 

आउटपुट (क्लोन)

{ 
    "firstName":"Fred", 
    "cars":[ 
     { 
      "model":"mersedes" 
     }, 
     { 
      "model":"bmw" 
     } 
    ] 
} 

मैं क्या कर सकते हैं कुछ की तरह

var human = myJson 
var clone = $.extend(true, {}, human) 
delete clone.lastName 
_.each(clone.cars, function(car)) 
{ 
    delete car.age 
} 

आप क्या आसान समाधान पता है?

+1

वहाँ $ .extend' का उपयोग कर 'क्लोन सदस्यों को फ़िल्टर करने के कोई रास्ता नहीं है, लेकिन आप अपने खुद के कार्यान्वयन कि क्षेत्रों को छोड़ देता है रोल कर सकता है ... –

+0

मैं एक बन जाएगा फ़ंक्शन जो किसी ऑब्जेक्ट को क्लोन करने के लिए स्वीकार करता है और आपके नए ऑब्जेक्ट में निकाले जाने वाले गुणों की सरणी (या शामिल) को स्वीकार करता है। JQuery में ऐसा करने के लिए अंतर्निहित विधि नहीं है। –

+0

Underscore.js में 'प्लक' फ़ंक्शन शामिल है, जो आप चाहते हैं कि एक प्रकार का व्यस्त संस्करण है: आप जो भी शामिल करना चाहते हैं उसे निर्दिष्ट करें, जिसे आप शामिल करना चाहते हैं उसे निर्दिष्ट करें। शायद यह आपके कार्यान्वयन के लिए एक प्रारंभिक बिंदु प्रदान कर सकता है? – Henrik

उत्तर

6

यदि आप प्रोटोटाइप ऑब्जेक्ट में जोड़ने में कोई फर्क नहीं पड़ता है, तो यह एक आसान समाधान है। आप इसे अपने स्वयं के उपयोग के लिए कुछ संशोधित करना चाह सकते हैं।

Object.prototype.deepOmit = function(blackList) { 
    if (!_.isArray(blackList)) { 
    throw new Error("deepOmit(): argument must be an Array"); 
    } 

    var copy = _.omit(this, blackList); 
    _.each(blackList, function(arg) { 
    if (_.contains(arg, '.')) { 
     var key = _.first(arg.split('.')); 
     var last = arg.split('.').slice(1); 
     copy[key] = copy[key].deepOmit(last); 
    } 
    }); 
    return copy; 
}; 

Array.prototype.deepOmit = function(blackList) { 
    if (!_.isArray(blackList)) { 
    throw new Error("deepOmit(): argument must be an Array"); 
    } 

    return _.map(this, function(item) { 
    return item.deepOmit(blackList); 
    }); 
}; 

तो फिर तुम जैसे एक वस्तु है जब:

var personThatOwnsCars = { 
    "firstName":"Fred", 
    "lastName":"McDonald", 
     "cars":[ 
      { 
       "type":"mersedes", 
       "age":5 
      }, 
      { 
       "model":"bmw", 
       "age":10 
      } 
     ] 
}; 

आप इस तरह जादू कर सकते हैं।

personThatOwnsCars.deepOmit(["firstName", "cars.age"]); 

या यहां तक ​​कि जादू भी!

[person1, person2].deepOmit(["firstName", "cars.age"]); 
+2

यदि आप पहले से ही अंडरस्कोर का उपयोग कर रहे हैं, तो संभव है कि प्रोटोटाइप के बजाय' _.mixin' का उपयोग करना बेहतर हो। –

5

यहां लॉनाश/अंडरस्कोर के आधार पर एक स्टैंडअलोन फ़ंक्शन है जो मैंने लिखा है जो वही करता है।

यह ऑब्जेक्ट या सरणी में प्रत्येक (मान, इंडेक्सऑर्की) जोड़ी के लिए कॉलबैक कॉल करता है और यदि सही परिणामस्वरूप ऑब्जेक्ट में उस जोड़ी को छोड़ देगा।

कॉलबैक को मूल्य के दौरे के बाद बुलाया जाता है ताकि आप अपनी स्थिति से मेल खाने वाले मूल्यों का एक संपूर्ण उप-पेड़ छोड़ सकें।

function deepOmit(sourceObj, callback, thisArg) { 
    var destObj, i, shouldOmit, newValue; 

    if (_.isUndefined(sourceObj)) { 
     return undefined; 
    } 

    callback = thisArg ? _.bind(callback, thisArg) : callback; 

    if (_.isPlainObject(sourceObj)) { 
     destObj = {}; 
     _.forOwn(sourceObj, function(value, key) { 
      newValue = deepOmit(value, callback); 
      shouldOmit = callback(newValue, key); 
      if (!shouldOmit) { 
       destObj[key] = newValue; 
      } 
     }); 
    } else if (_.isArray(sourceObj)) { 
     destObj = []; 
     for (i = 0; i <sourceObj.length; i++) { 
      newValue = deepOmit(sourceObj[i], callback); 
      shouldOmit = callback(newValue, i); 
      if (!shouldOmit) { 
       destObj.push(newValue); 
      } 
     } 
    } else { 
     return sourceObj; 
    } 

    return destObj; 
} 

कुछ नमूने

var sourceObj = { 
    a1: [ undefined, {}, { o: undefined } ], 
    a2: [ 1, undefined ], 
    o: { s: 's' } 
}; 

deepOmit(sourceObj, function (value) { 
    return value === undefined; 
}); 
//=> { a1: [ {}, {} ], a2: [ 1 ], o: { s: 's' }} 

//omit empty objects and arrays too 
deepOmit(sourceObj, function (value) { 
    return value === undefined || 
     (_.isPlainObject(value) && !_.keys(value).length) || 
     (_.isArray(value) && !value.length); 
}); 
//=> { a2: [ 1 ], o: { s: 's' }} 

//indexOrKey is the string key or the numeric index if the object is array 
deepOmit([ 0, 1, 2, 3, 4 ], function (value, indexOrKey) { 
    return indexOrKey % 2; 
}); 
//=> [ 0, 2, 4 ] 
संबंधित मुद्दे