7

JSON データのストレージ要件を、既知の一連のデフォルトに対して差分化することで削減しようとしています。基本的に、私が欲しいのは.extend()、次のテストが任意の JSON 互換オブジェクトに対してパスするように、jQuery の関数の逆です。

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

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

独自の を書き始める前にget_delta()、既存の実装を知っている人はいますか?

4

3 に答える 3

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

また、N 個のオブジェクトに対して機能するように微調整することもできますが、もう少し考える必要があります。

于 2011-02-22T17:17:59.943 に答える
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 への追加を返すことにより、これを拡張して完全な差分を提供できます。

このコードにはバグがないわけではありません。オブジェクト プロトタイプと関数はブラウザーによって異なる方法で処理されますが、データ構造のデモンストレーションとしては十分です。

于 2010-12-13T22:46:54.103 に答える
1

これがトピックのスターターに関連するのに少し遅れていることは承知していますが、_.omit(object, *keys)Underscore.js の関数を確認することをお勧めします。それはまさにそれを行います。

于 2014-04-29T22:40:26.237 に答える