SORU
20 Aralık 2011, Salı


Genel derin iki nesne arasındaki fark

İki nesne var: oldObj newObj.

oldObj verileri bir form doldurmak için kullanılan ve newObj kullanıcı sonucu bu formdaki verileri değiştirme ve gönderme.

Her iki nesnenin de derin yani. nesneleri vb nesneleri veya dizi özelliklere sahiptir - n düzeyleri derin olabilir, böylece diff algoritması özyinelemeli olması gerekir.

Şimdi değil sadece en iyi şekilde temsil etmek için nasıl değişti (eklenen/silinen/güncelleme gibi) newObj oldObj gelen de anlamaya ihtiyacım var.

Düşüncelerimi sadece 10 ** form üzerinde bir nesne döndürecektir genericDeepDiffBetweenObjects bir yöntem inşa etmek olduğunu düşündüm ama sonra şimdiye kadar: başkası bunu daha önce. gerekli olması gerekir

Hiç kimseyle bir kütüphane ya da bunu fark (hala JSON seri hale getirilebilir bir şekilde) temsil eden daha iyi bir yolu vardır belki, bir parça kodu biliyor mu?

Güncelleme:

newObj, aynı nesne yapısını kullanarak form üzerinde nesneleri içine Tüm özellik değerlerini çevirerek güncelleştirilmiş verileri temsil etmek için daha iyi bir yol düşünüyorum:

{type: '<update|create|delete>', data: <propertyValue>}

newObj.prop1 = 'new value' oldObj.prop1 = 'old value' returnObj.prop1 = {type: 'update', data: 'new value'} oluştururdu

Güncelleme 2:

Oluyor gerçekten kıllı gidince özellikleri olan diziler beri dizi [1,2,3] olmalı sayılır olarak eşit [2,3,1] olduğu için yeteri kadar basit diziler değer temelli türleri gibi string, int ve bool, ama alır gerçekten zor başa gelince diziler referans tipleri gibi nesneler ve diziler.

Örnek eşit olmak kurmak diziler:

[1,[{c: 1},2,3],{a:'hey'}] and [{a:'hey'},1,[3,{c: 1},2]]

Sadece derin değer eşitliği bu tür kontrol etmek için, ama aynı zamanda olabilecek değişiklikleri göstermek için iyi bir yol anlamaya oldukça karmaşıktır.

CEVAP
21 Aralık 2011, ÇARŞAMBA


21* *test edebilirsiniz istediğiniz ne yaptığını küçük bir sınıf yazdım.

Teklifinizi farklı olan tek şey dizilerin kendi elemanları sırası değil aynı ise eşit olmadığını düşünüyorum çünkü [1,[{c: 1},2,3],{a:'hey'}] and [{a:'hey'},1,[3,{c: 1},2]] aynı olduğunu düşünüyorum, bilmiyorum. Tabii ki bu gerekirse değiştirilebilir. Ayrıca bu kod daha da artırmak için işlev bağımsız değişken olarak kullanılacak biçim diff nesne keyfi şekilde dayalı geçti ilkel değerler (artık bu iş bitti "compareValues" yöntemi).

var deepDiffMapper = function() {
    return {
        VALUE_CREATED: 'created',
        VALUE_UPDATED: 'updated',
        VALUE_DELETED: 'deleted',
        VALUE_UNCHANGED: 'unchanged',
        map: function(obj1, obj2) {
            if (this.isFunction(obj1) || this.isFunction(obj2)) {
                throw 'Invalid argument. Function given, object expected.';
            }
            if (this.isValue(obj1) || this.isValue(obj2)) {
                return {type: this.compareValues(obj1, obj2), data: obj1 || obj2};
            }

            var diff = {};
            for (var key in obj1) {
                if (this.isFunction(obj1[key])) {
                    continue;
                }

                var value2 = undefined;
                if ('undefined' != typeof(obj2[key])) {
                    value2 = obj2[key];
                }

                diff[key] = this.map(obj1[key], value2);
            }
            for (var key in obj2) {
                if (this.isFunction(obj2[key]) || ('undefined' != typeof(diff[key]))) {
                    continue;
                }

                diff[key] = this.map(undefined, obj2[key]);
            }

            return diff;

        },
        compareValues: function(value1, value2) {
            if (value1 === value2) {
                return this.VALUE_UNCHANGED;
            }
            if ('undefined' == typeof(value1)) {
                return this.VALUE_CREATED;
            }
            if ('undefined' == typeof(value2)) {
                return this.VALUE_DELETED;
            }

            return this.VALUE_UPDATED;
        },
        isFunction: function(obj) {
            return {}.toString.apply(obj) === '[object Function]';
        },
        isArray: function(obj) {
            return {}.toString.apply(obj) === '[object Array]';
        },
        isObject: function(obj) {
            return {}.toString.apply(obj) === '[object Object]';
        },
        isValue: function(obj) {
            return !this.isObject(obj) && !this.isArray(obj);
        }
    }
}();


var result = deepDiffMapper.map({
      a:'i am unchanged',
      b:'i am deleted',
      e:{ a: 1,b:false, c: null},
      f: [1,{a: 'same',b:[{a:'same'},{d: 'delete'}]}]
  },
  {
      a:'i am unchanged',
      c:'i am created',
      e:{ a: '1', b: '', d:'created'},
      f: [{a: 'same',b:[{a:'same'},{c: 'create'}]},1]

  });
console.log(result);

Bunu Paylaş:
  • Google+
  • E-Posta
Etiketler:

YORUMLAR

SPONSOR VİDEO

Rastgele Yazarlar

  • Bryan Smith

    Bryan Smith

    12 Mart 2006
  • Damian Winter

    Damian Winte

    27 ŞUBAT 2007
  • thenewboston

    thenewboston

    4 ŞUBAT 2008