2010-08-04 14 views
7

के विपरीत मैं जेएसओएन डेटा के लिए डिफ़ॉल्ट रूप से ज्ञात सेट के खिलाफ इसे वितरित करके भंडारण आवश्यकताओं को कम करने के लिए देख रहा हूं। असल में, क्या मैं चाहता हूँ jQuery के .extend() समारोह के लिए एक व्युत्क्रम, जैसे कि निम्नलिखित परीक्षण मनमाना JSON-संगत वस्तुओं के लिए गुजरता है:jQuery.extend (सत्य, ...)

function test_delta(defaults, delta) { 
    var current = $.extend(true, {}, defaults, delta); 

    QUnit.same(get_delta(current, defaults), delta); 
} 

इससे पहले कि मैं लेखन शुरू मेरे अपने get_delta(), मौजूदा कार्यान्वयन के बारे में पता है?

+0

आपको इसे स्वयं को, हार्ड (नेस्टेड लूप) तरीके से संभालना होगा। जैसा कि आप शायद जानते हैं। यदि आपके JSON डेटा में मनमानी गहराई है तो यह और भी मजेदार है। –

+0

हाँ, मैं पहले से ही कुछ दिलचस्प किनारे के मामलों के साथ आया हूँ; यही कारण है कि मैंने सोचा कि मैं खुद को खोदने से पहले "एसओ ओरेकल" से पूछूंगा। ठीक है। :-) –

+0

शुरू करने के लिए एक अच्छी जगह [jQuery स्रोत] में jQuery.fn.extend फ़ंक्शन को देखेगी (http://ajax.googleapis.com/ajax/libs/jquery/1/jquery.js)। – calvinf

उत्तर

1

जो आप वास्तव में खोज रहे हैं वह एक वस्तु diff (erential) एल्गोरिदम है।



function diff (obj1, obj2) { 
    var delta = {}; 

    for (var x in obj1) { 
     if (obj2.hasOwnProperty(x)) { 
      if (typeof obj2[x] == "object") { 
       //recurse nested objects/arrays 
       delta[x] = diff(obj1[x], obj2[x]); 
      } 
      else { 
       //if obj2 doesn't match then - modified attribute 
       if (obj2[x] != obj1[x]) { 
        delta[x] = obj1[x]; 
       } 
      }   
     } 
     else { 
      //obj2 doesn't have this - new attribute 
      delta[x] = obj1[x]; 
     } 
    } 

    return delta; 
} 

alert( 
    JSON.stringify(
    diff({ hello : 'world', gone : 'fishing' }, 
      { hello : 'world' }) 
) 
); 

//outputs: 
{ gone : 'fishing' } 

आप देख सकते हैं कि यह एक बहुत ही बुनियादी कार्यान्वयन है - - आप इस विस्तार कर सकता है अतिरिक्त लौटने एक अलग वस्तु में obj2 करने से पूरी तरह से अंतर प्रदान करने के लिए

भी लिखना मुश्किल नहीं।

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

+0

मैंने अपना खुद का कार्यान्वयन करने के लिए एक स्टैब लिया था, लेकिन पर्याप्त अस्पष्ट मामलों (विशेष रूप से सरणी और हटाए गए गुणों के साथ) थे जिन्हें हमने बस डेटाबेस कॉलम को विस्तारित करने का निर्णय लिया था। –

1

कोशिश कुछ:

jQuery.extend({ 
    deltaExtend: function(deep, target, defaults, delta){ 
     var result = jQuery.extend.apply(jQuery, arguments); 
     jQuery(result).data('delta', delta); 
     jQuery(result).data('defaults', defaults); 
     return result; 
    } 
}); 

उपयोग:

var result = $.deltaExtend(true, {}, defaults, delta); 
$(result).data('delta') //returns delta object 
$(result).data('defaults') //returns default object 

यह भी एन वस्तुओं के लिए काम इसे पाने के लिए बदलाव किया जा सकता है, बस थोड़ी और सोच की आवश्यकता है।

+0

यह एक बहुत ही रोचक विचार है! दुर्भाग्यवश, मेरे मामले में "परिणाम" ऑब्जेक्ट बनाने में '$ .extend' का उपयोग नहीं किया जाता है। यह एक पोर्टल सिस्टम के लिए था, जहां प्रत्येक पोर्टलेट अपनी डिफ़ॉल्ट सेटिंग्स को परिभाषित कर सकता था। "वर्तमान" सेटिंग्स को पृष्ठ के जीवनकाल में स्वतंत्र रूप से संशोधित किया जाएगा और, जब पोर्टलेट की स्थिति को सर्वर पर वापस सहेजने के लिए समय आया, तो मैं भंडारण आवश्यकताओं को कम करने के लिए "अंधे" डेल्टा करने की उम्मीद कर रहा था। –

+0

मेरे पास एक और समाधान है, आप कौन से ब्राउज़र का समर्थन कर रहे हैं, और कौन से संस्करण, विशेष रूप से आप आईई

1

मुझे पता है कि यह विषय स्टार्टर से प्रासंगिक होने में थोड़ा देर हो चुकी है, लेकिन हो सकता है कि आप Underscore.js से _.omit(object, *keys) फ़ंक्शन देखें। यह बस यही करता है।

+0

लेकिन आप 'चाबियाँ' कैसे जानते हैं? – Bergi

+0

कुंजी उस ऑब्जेक्ट से आती हैं जहां डिफ़ॉल्ट संग्रहित होते हैं। '_.keys (defaultObject) 'आपको इसकी चाबियों की एक सरणी देता है। – oley

+0

आपको शायद अपने उत्तर में उल्लेख किया जाना चाहिए ... और ध्यान दें कि यह विधि केवल * अतिरिक्त * गुणों के लिए काम करती है, सभी * बदले * के लिए नहीं। – Bergi

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