2013-08-22 1 views
5

Ich habe 2 Arrays zu finden, die eine newVal ist und das andere ist origValVergleichen 2 Arrays von Objekten mit Unders die differnce

zu definieren

orig:

[ 
{"ListingId":1762276,"Rating":3,"ListPrice":7411828,"PropertyType":"Residential"}, 
{"ListingId":1826692,"Rating":3,"ListPrice":650000,"PropertyType":"Residential"}, 
{"ListingId":1833283,"Rating":4,"ListPrice":950000,"PropertyType":"Residential"}, 
{"ListingId":1832134,"Rating":3,"ListPrice":850000,"PropertyType":"Residential"}, 
{"ListingId":1829932,"Rating":4,"ListPrice":750000,"PropertyType":"Residential"}, 
{"ListingId":1827548,"Rating":5,"ListPrice":650000,"PropertyType":"Residential"} 
] 

neu:

[ 
{"ListingId":1762276,"Rating":2,"ListPrice":7411828,"PropertyType":"Residential"}, 
{"ListingId":1826692,"Rating":3,"ListPrice":650000,"PropertyType":"Residential"}, 
{"ListingId":1833283,"Rating":4,"ListPrice":950000,"PropertyType":"Residential"}, 
{"ListingId":1832134,"Rating":3,"ListPrice":850000,"PropertyType":"Residential"}, 
{"ListingId":1829932,"Rating":4,"ListPrice":750000,"PropertyType":"Residential"}, 
{"ListingId":1827548,"Rating":5,"ListPrice":650000,"PropertyType":"Residential"} 
] 

Wenn ich eine der Bewertungen in "Neu" ändere, wie kann ich diese Änderung erkennen und das geänderte Objekt abrufen?

Es wird immer nur eine Änderung geben, obwohl das nicht wichtig ist.

FYI: Diese Arrays von einem Anjularjs watchcollection produziert werden

$scope.$watchCollection('items', function (new, old) { 

}, true); 

Danke, Stephen

+0

Sind diejenigen, die gleichen Objekte in dem Array (das heißt '' === Identität) oder sind sie nur ähnlich aussehenden? – Bergi

+0

Welches Ergebnis benötigen Sie? Der Index des geänderten Objekts im Array, das neue geänderte Objekt, das alte geänderte Objekt, die Bewertung? – Bergi

+0

Ich würde das geänderte Objekt bevorzugen, zB {"ListingId": 1762276, "Rating": 2, "ListPrice": 7411828, "PropertyType": "Wohnhaft"} –

Antwort

10

einen Blick auf diese nehmen:

var a = [ 
{"ListingId":1762276,"Rating":3,"ListPrice":7411828,"PropertyType":"Residential"}, 
{"ListingId":1826692,"Rating":3,"ListPrice":650000,"PropertyType":"Residential"}, 
{"ListingId":1833283,"Rating":4,"ListPrice":950000,"PropertyType":"Residential"}, 
{"ListingId":1832134,"Rating":3,"ListPrice":850000,"PropertyType":"Residential"}, 
{"ListingId":1829932,"Rating":4,"ListPrice":750000,"PropertyType":"Residential"}, 
{"ListingId":1827548,"Rating":5,"ListPrice":650000,"PropertyType":"Residential"} 
]; 

var b = [ 
{"ListingId":1762276,"Rating":2,"ListPrice":7411828,"PropertyType":"Residential"}, 
{"ListingId":1826692,"Rating":3,"ListPrice":650000,"PropertyType":"Residential"}, 
{"ListingId":1833283,"Rating":4,"ListPrice":950000,"PropertyType":"Residential"}, 
{"ListingId":1832134,"Rating":3,"ListPrice":850000,"PropertyType":"Residential"}, 
{"ListingId":1829932,"Rating":4,"ListPrice":750000,"PropertyType":"Residential"}, 
{"ListingId":1827548,"Rating":5,"ListPrice":650000,"PropertyType":"Residential"} 
] 

var difference = function(array){ 
    var rest = Array.prototype.concat.apply(Array.prototype, Array.prototype.slice.call(arguments, 1)); 

    var containsEquals = function(obj, target) { 
    if (obj == null) return false; 
    return _.any(obj, function(value) { 
     return _.isEqual(value, target); 
    }); 
    }; 

    return _.filter(array, function(value){ return ! containsEquals(rest, value); }); 
}; 

console.log(JSON.stringify(difference(b, a))); 
> [{"ListingId":1762276,"Rating":2,"ListPrice":7411828,"PropertyType":"Residential"}] 

Der Code auf die ursprüngliche Funktion difference aus Strich basiert, aber es führt einen tiefen Vergleich zwischen Objekten mit isEqual .

+0

Und danke für den Debugging-Tipp mit JSON.stringify –

+1

Es ist genial , Was es macht. Ich wünschte ich könnte den Code verstehen. – mcktimo

3

Wenn der Auftrag, tun eine einfache Iteration es nicht ändern. Unders bietet die find method für diese Aufgabe:

var changedObj = _.find(newVal, function(obj, index) { 
    return obj.Rating != oldVal[index].Rating; 
}); 
0

Wie wäre:

const current = [{name:'a'},{name:'b'},{name:'c'}] 
const update = [{name:'x'},{name:'a'},{name:'b'},{name:'f'}] 
const records = current.concat(update); 
const diff = {}; 
diff.in = [] 
diff.out = []; 
records.forEach(item => { 
    if(!current.find(cur => item.name == cur.name))diff.in.push(item) 
    if(!update.find(up => item.name == up.name))diff.out.push(item) 
})