2015-02-20 7 views
12

Sto provando a confrontare due oggetti con il trattino basso.Utilizzo di underscore.js per confrontare due oggetti

Oggetto 1 (Filtro)

{ 
    "tuxedoorsuit":"tuxedoorsuit-tuxedo", 
    "occasions":"occasions-wedding" 
} 

Oggetto 2 (Proprietà)

{ 
    "tuxedoorsuit":"tuxedoorsuit-tuxedo", 
    "occasions":"occasions-wedding", 
    "occasions":"occasions-prom", 
    "product_fit":"product_fit-slim", 
    "colorfamily":"colorfamily-black" 
} 

voglio tornare vero quando tutti gli elementi di Object 1 si trovano all'interno Oggetto 2. Quali sarebbe il miglior metodo di sottolineatura da usare per questo?

+4

Che dire http: // underscorejs .org/# isEqual e http://underscorejs.org/#isMatch? –

+1

@ ArnaldoIgnacioGasparVéjar: dovresti fare una risposta. È molto meglio di quello attualmente accettato. – Bergi

+0

@Berg: Sono d'accordo che 'isMatch' sarebbe molto meglio. Ma in realtà è interessante notare che non funzionerà in questo caso, perché "Object 2" è malformato. Ha due volte le stesse 'occasioni' della proprietà.[isMatch] (http://underscorejs.org/docs/underscore.html#section-106) lancia "Oggetto 2" su un oggetto standard e mantiene solo l'ultimo valore di questa proprietà: 'occasions-prom'. Restituirà quindi 'false'. – slaur4

risposta

20

Edit: Secondo Arnaldo's comment, è possibile utilizzare isMatch la funzione, come questo

console.log(_.isMatch(object2, object1)); 

dice la descrizione,

_.isMatch(object, properties)

ti dice se le chiavi e valori in proprietà sono contenute in oggetto.

Se volete iterare te stesso, basta usare _.keys e _.every, come questo

_.every(_.keys(object1), function(currentKey) { 
    return _.has(object2, currentKey) && 
        _.isEqual(object1[currentKey], object2[currentKey]); 
}); 

o la versione incatenato,

var result = _.chain(object1) 
    .keys() 
    .every(function(currentKey) { 
     return _.has(object2, currentKey) && 
      _.isEqual(object1[currentKey], object2[currentKey]); 
    }) 
    .value(); 

Se il risultato è true, vuol dire che tutte le chiavi in ​​object1 sono in object2 e anche i loro valori sono uguali.

Questo praticamente scorre tutte le chiavi di object1 e verifica se il valore corrispondente alla chiave in object1 è uguale al valore in object2.

+0

Come utilizzarlo all'interno di _.filter? – Casey

+0

@Casey Si prega di modificare la domanda e includere tutte le informazioni – thefourtheye

+0

Questo ha funzionato alla grande! Sono stato in grado di modificarlo un po 'per lavorare all'interno di _.filter(). Grazie! – Casey

6

Per confrontare due oggetti utilizzando underscore.js

**isEqual :** _.isEqual(object, other) 

Esegue un profondo confronto ottimale tra i due oggetti, per determinare se devono essere considerati uguali.

Es:

var stooge = {name: 'moe', luckyNumbers: [13, 27, 34]}; 
    var clone = {name: 'moe', luckyNumbers: [13, 27, 34]}; 
    _.isEqual(stooge, clone) 
     Returns True 
+1

Mentre 'isEqual' è abbastanza utile, non funzionerà se l'altro oggetto ha una proprietà aggiuntiva, come nel caso dell'OP. –

+0

Non funzionerà anche se l'ordine delle chiavi non è identico: / –

0

Sulla base di funzione precedente creato semplice consolante out funzione:

var compareMe = function (obj1, obj2, parentKey) { 
    parentKey = parentKey || ''; 
    _.each(_.keys(obj1), function (key) { 
    if(_.isObject(obj1[key])) { 
     compareMe(obj1[key], obj2[key], parentKey + key + '.') 
    } else { 
     if (!_.has(obj2, key) || !_.isEqual(obj1[key], obj2[key])) { 
      console.log(parentKey + key, obj1[key], obj2[key]); 
     } 
    } 
    }) 
}; 

E chiamare come: compareMe (obj1, obj1)