2015-08-01 17 views
5

Mam interfejs API i chcę potwierdzić, że zwrócono co najmniej oczekiwane dane. Nie obchodzi mnie, czy zwrócono więcej danych.Jak zapewnić częściowo głębokie równe/porównać obiekty w javascript?

Dlatego chcę porównać dwa obiekty (expected i actual) gdzie wszystkie atrybuty expected musi być równa actual, ale actual może zawierać więcej atrybutów:

var expected = { 
    foo: 1, 
    bar: { 
     x1: 42, 
     a1: [ 
      1, 
      2, 
      { 
       x: 7 
      } 
     ] 
    } 
} 

var actual = { 
    foo: 1, 
    whatever: 55, // to be ignored 
    additional: { // to be ignored 
     ignore: 1 
    }, 
    bar: { 
     x1: 42, 
     a1: [ 
      1, 
      2, 
      { 
       x: 7, 
       y: 8 // to be ignored 
      } 
     ] 
    } 
} 

partiallyEqual(expected, actual) // returns true 

Jeszcze kilka przykładów:

partiallyEqual({x: 1}, {a:2, x:1}) // return true 
partiallyEqual({x: 1}, {a:2, x:2}) // return false (x is different) 

Tablice mogą (opcjonalnie) być częściowo równoważne, jeśli actual zawiera dodatkowe elementy.

partiallyEqual([1, 3], [1, 2, 3]) // return true 
partiallyEqual([3, 1], [1, 2, 3]) // return false (different order) 
+1

Czy próbowałeś Chai za 'deepEqual'? – Gyandeep

+0

tak, ale jest ściśle równy, id nie ignoruje żadnych atrybutów –

+0

Ponieważ twój przypadek użycia jest małą odmianą 'deepEqual', proponuję przejrzeć tutaj: https: //github.com/chaijs/deep-eql /blob/master/lib/eql.js Dostosuj go do swoich potrzeb. – Gyandeep

Odpowiedz

0

Używam tej funkcji rekurencyjnej, że pisałem jakiś czas temu:

Object.prototype.equals = function(to) { 
    for (var prop in to) { 
     if (this.hasOwnProperty(prop) && to.hasOwnProperty(prop)) { 
      if (to[prop] && typeof this[prop] == "object" && typeof to[prop] == "object") { 
       if (!this[prop].equals(to[prop])) { 
        return false 
       } 
      } else if (this[prop] != to[prop]) { 
       return false 
      } 
     } 
    } 
    return true; 
}; 

({ x: { a: 1, b: 2 } }).equals({ x: { a: 1, b: 2 } }) => true 
({ x: { a: 1, b: 2 } }).equals({ x: { a: 1, b: 1 } }) => false 
({ x: [1,2] }).equals({ x: { 1:1,2:2 } }) => true (doesn't differentiate between array and/or object) 

Ta funkcja zwróci false, gdy tylko stwierdzi jakąś różnicę stary vs nowego obiektu. Nowy obiekt może zawierać wszystko, jeśli ma wszystkie właściwości starego obiektu.

+0

Zobacz [Jak zdefiniować metodę w javascript na Array.prototype i Object.prototype, aby nie pojawiały się w pętli for] (http://stackoverflow.com/a/13296897/1048572) i wykonaj swój 'Obiekt .prototype' rozszerzenie właściwie. – Bergi

+1

użyć funkcji o nazwie prop że robi to: function (do rekwizyt, nazwisko, funkcjono) { 'Object.defineProperty (to.prototype, nazwę, { wartość: FUNC zapisu: prawda, konfigurowalne: true }) ; funkcja powrotu; } ' jest stosowany jako daniele ' podpory (Object 'równa', funkcja (TO) {...}) ' nich może być połączony: ' podpory (Object 'równa', funkcja (na) {prop (Array, 'equals', function (to) {...})}) ' A przy okazji, rozszerzenie obiektu rozszerza także Array, ponieważ rozszerza WSZYSTKO – Akxe

0

Głębokie równe może być trudne w różnych przypadkach, na przykład NaN !== NaN i mogą występować odwołania kołowe. Napisałem ostatnio prostą funkcję głębokiego równego czeku z rekurencyjnym i cyklicznym sprawdzaniem referencji, która powinna być całkiem prosta do naśladowania. Możesz po prostu zignorować część sprawdzania długości, aby częściowo zrobić to samo.

kod źródłowy na github: https://github.com/ryancat/simple-deep-equal

Powiązane problemy