2015-08-12 2 views
2

Предполагая, что у нас есть 2 массива, A (источник) и B (сохраняется).Jascript - Сравнивая 2 массива объекта самым быстрым и чистым способом

var A = [ 
     { id: 1, value: 'Product Name 1' }, 
     { id: 2, value: 'Product Name 2' }, 
     { id: 3, value: 'Product Name 3' }, 
     { id: 4, value: 'Product Name 4' }, 
     { id: 5, value: 'Product Name 5' } 
] 


var B = [ 
     { id: 1, value: 'Product Name 1' }, 
     { id: 2, value: 'Changed Name' }, 
     { value: 'New Product' } 
] 

В основном то, что я хочу сделать, это сравнить оба массива и проверить массив B, элементы не присутствуют из массива А, которые были удалены, те, которые имели свойство «значение» изменилось, который получил отредактирован, и какие новые, которые добавлены (в основном без id).

Логика выглядит, что (при условии, что каждый из А и В один элемент из каждого массива)

if A.id == B.id and A.value !== B.value then Edit 

B.id doesnt exist then New 

B.id is not on A then Deleted 

Мне нужно, чтобы иметь массив всех элементов, которые получили новые, редактировать и удалять

Ожидаемый массив будет

added = [ 
     { value: 'New Product'} 
] 

edited = [ 
     { id: 2, value: 'Changed Name' } 
] 

deleted = [ 
     { id: 3, value: 'Product Name 3' }, 
     { id: 4, value: 'Product Name 4' }, 
     { id: 5, value: 'Product Name 5' } 
] 
+0

Вы можете оставить свой ожидаемый массив – Raghavendra

ответ

4

Вы можете использовать filter и some, как и

var A = [ 
    { id: 1, value: 'Product Name 1' }, 
    { id: 2, value: 'Product Name 2' }, 
    { id: 3, value: 'Product Name 3' }, 
    { id: 4, value: 'Product Name 4' }, 
    { id: 5, value: 'Product Name 5' } 
] 

var B = [ 
    { id: 1, value: 'Product Name 1' }, 
    { id: 2, value: 'Changed Name' }, 
    { value: 'New Product' } 
] 

// deleted 
var deleted = A.filter(function (a) { 
    return !B.some(function (b) { return b.id === a.id }) 
}) 
var changed = A.filter(function (a) { 
    return B.some(function (b) { return (b.id === a.id) && (b.value !== a.value) }) 
}) 
var added = B.filter(function (b) { 
    return !A.some(function (a) { return b.id === a.id }) 
}) 

console.log(deleted); 
console.log(changed); 
console.log(added); 

changed массив в настоящее время возвращает элементы А, если вы хотите элементы Б, просто поменять местами А и В в этом кусочке кода.

0

Вы можете сделать что-то вроде этого (пример использует lodash утилиту библиотеки):

var create = _.cloneDeep(A); 
var delete = _.cloneDeep(B); 
var edit = _.remove(create, function(c) { 
    return _.some(delete, function(d, dIndex) { 
     if (c.id === d.id) { 
      d.splice(dIndex, 1); 
      return true; 
     } 
     return false; 
    }); 
}); 
0

можно непосредственно использовать как

result = []; 
for(var index in A) { 
    var item = A[index],index1; 
    for(index1 in B) { 
     var item1 = B[index1]; 
     if(item1.id == item.id) { 
      result.push(item1); 
      break; 
     } 
    } 
    if(index1 == B.length-1) 
     result.push(item); 
} 
0

.reduce() + .find() (ES6)

var result = { new: [], edited: [], deleted: [] }; 

result = B.reduce(function (l, r) { 
    if (typeof r.id === "undefined") { 
     l.new.push(r); 
    } else { 
     var elementInA = this.find(function (el) { 
      return el.id === r.id; 
     }); 

     if (typeof elementInA === "undefined") { 
      l.deleted.push(r); 
     } else if (elementInA.value !== r.value) { 
      l.edited.push(r); 
     } 
    } 

    return l; 
}.bind(A), result); // .bind(A) to get the <A> array available as <this> in the reduce callback. 
         // Of course A.find instead of this.find would also be possible 

console.log(result); // {"new":[{"value":"New Product"}],"edited":[{"id":2,"value":"Changed Name"}],"deleted":[]} 

fiddle

Смежные вопросы