13

У меня есть два массива JavaScript orig (исходный массив объектов) и update (обновленный массив объектов), которые имеют одинаковую длину и содержат объекты, и я хочу вывести различия между каждой парой объектов.Как найти различия между двумя массивами JavaScript объектов?

Пример:

var orig = [{enabled:"true", name:"Obj1", id:3},{enabled:"true", name:"Obj2", id:4}]; 

var update = [{enabled:"true", name:"Obj1", id:3}, {enabled:"true", name:"Obj2-updated", id:4}]; 

Вывод должен быть: name:"Obj2-updated"

я осуществил что-то, но она нуждается в оптимизации ...

for(var prop=0; prop<orig.length; prop++) { 
    for(prop=0; prop<update.length; prop++) { 
    if(orig[prop].enabled != update.enabled) { console.log(update.enabled) } 
    if(orig[prop].name != update[prop].name) { console.log(update[prop].name) } 
    if(orig[prop].id != update[prop].id) { console.log(update[prop].id) } 
    } 
} 
+0

- это вывод строки или объекта? или массив с объектами или строками, или? –

+0

Хотя я не знаю вашего прецедента, мне кажется нецелесообразным иметь только список измененных значений, не зная, какой ключ и в каком объекте, который изменил значение, существует; вы уверены, что вам больше не нужны детали? Я не пытаюсь умалить ваш вопрос, но я пытаюсь предвидеть, каким может быть ваш следующий вопрос, если вы ошибаетесь в отношении необходимости изменения значений. –

+0

Мне просто нужен этот вывод для создания строкового текста, который гласит: «Эй, вы изменили Obj2 на Obj2-updated». Но мне нужно только знать, какое свойство было изменено. – Valip

ответ

12

Вы можете фильтровать ключи и получить набор результатов с помощью обновленных ключей.

var orig = [{ enabled: "true", name: "Obj1", id: 3 }, { enabled: "true", name: "Obj2", id: 4 }], 
 
    update = [{ enabled: "true", name: "Obj1", id: 3 }, { enabled: "true", name: "Obj2-updated", id: 4 }], 
 
    difference = []; 
 

 
orig.forEach(function (a, i) { 
 
    Object.keys(a).forEach(function (k) { 
 
     if (a[k] !== update[i][k]) { 
 
      difference.push({ id: update[i].id, key: k, value: update[i][k], index: i }); 
 
     } 
 
    }); 
 
}); 
 

 
console.log(difference);

+0

Можете ли вы сообщите мне, есть ли способ зарегистрировать измененный объект? В этом случае '{enabled:" true ", name:" Obj2-updated ", id: 4}' – Valip

+7

И вы видите, вот почему [я спросил вас раньше, если вы уверены, что вам нужно только измененное значение ] (http://stackoverflow.com/questions/39074429/how-to-find-differences-between-two-javascript-arrays-of-objects#comment65497981_39074429). До сих пор вопрос изменился, и требуемые значения возвращаемого значения изменились с измененного значения на измененное значение * и * на ключ для этого значения, а теперь * вы решили, что хотите, чтобы все измененные значения объект, который будет возвращен. Пожалуйста, возьми пять минут * до того, как задал вопрос, чтобы правильно составить вопрос. –

+1

@PavelValeriu, если бы я знал, ** как ** результат должен выглядеть, я мог бы дать ответ. так что вам нужно? объект или индекс или пару ключ/значение или что? –

6

Предполагая, что имена свойств обоих одинаковы и значения являются просто примитивными (нет объектов, массивов и т. д.):

Object.keys(orig) 
     .forEach((key) => { 
     if(orig[ key ] !== update[ key ]) { 
      console.log(update[key]); 
     } 
     }); 
+0

Могу ли я использовать 'orig [prop] [key]'? – Valip

+0

@PavelValeriu Что делать? В вашем примере кода вы предполагаете, что обе переменные содержат массивы, но они фактически являются объектами. Итак, ваш '.length' на самом деле не должен работать (если вы не установите его где-то явно) – Sirko

+0

Не стоит отправлять отдельный ответ, учитывая, что он по сути тот же, но поскольку OP только хочет знать, какие значения разные (без ссылки на клавиши, по-видимому) немного легче использовать ['Object.values ​​()'] (https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Global_Objects/Object/values), а не получать доступ к значениям объекта через ключи на каждой итерации (для этого требуется, чтобы в браузере реализован «Object.values ​​()», хотя, очевидно). –

3

Используйте Object.keys, чтобы просмотреть ваш объект. Что-то вроде:

var orig = { 
 
    enabled: "true", 
 
    name: "Obj1", 
 
    id: 3 
 
}; 
 

 
var update = { 
 
    enabled: "true", 
 
    name: "Obj1-updated", 
 
    id: 3 
 
}; 
 

 
var diff = {}; 
 

 
Object.keys(orig).forEach(function(key) { 
 
    if (orig[key] != update[key]) { 
 
    diff[key] = update[key]; 
 
    }; 
 
}) 
 

 
console.log(diff);

3

Вы можете использовать один цикл, чтобы пройти через свойства исходного объекта и проверить на обновленном объекте, чтобы выяснить, какие свойства были изменены.

var orig = { 
 
    enabled: "true", 
 
    name: "Obj1", 
 
    id: 3 
 
}; 
 

 
var update = { 
 
    enabled: "true", 
 
    name: "Obj1-updated", 
 
    id: 3 
 
}; 
 

 
for (var key in orig) { 
 
    if (orig[key] !== update[key]) { 
 
    console.log(key + ': ' + update[key]); 
 
    } 
 
}

0

Вы можете использовать библиотеку как lodash или Ramda сделать это в сжатой форме. В случае с Ramda вы можете сделать: R.difference(update, orig);

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