Сравнение двух массивов объектов и исключение элементов, которые соответствуют значениям в новый массив в JS
вот мой пример использования в JavaScript:
У меня есть два массива объектов, которые имеют свойства, которые соответствуют (id и name).
var result1 = [
{id:1, name:'Sandra', type:'user', username:'sandra'},
{id:2, name:'John', type:'admin', username:'johnny2'},
{id:3, name:'Peter', type:'user', username:'pete'},
{id:4, name:'Bobby', type:'user', username:'be_bob'}
];
var result2 = [
{id:2, name:'John', email:'[email protected]'},
{id:4, name:'Bobby', email:'[email protected]'}
];
var props = ['id', 'name'];
Моя цель - иметь еще один массив объектов, содержащий только те элементы, которые не совпадают. Вот так:
var result = [
{id:1, name:'Sandra'},
{id:3, name:'Peter'}
];
Я знаю, что есть способ сделать это, перейдя из результата1, сравнивая каждый объект с объектами result2, затем сравнивайте их ключи, и если did'n соответствует, поместите значения в другой объект, а затем вставьте его в новый массив, но мне интересно, есть ли более элегантный способ, например, использовать lo-dash или подчеркивание или что-то подобное.
Спасибо!
Ответы
Ответ 1
Просто используя Итерационные методы массива, встроенные в JS, подходят для этого:
var result1 = [
{id:1, name:'Sandra', type:'user', username:'sandra'},
{id:2, name:'John', type:'admin', username:'johnny2'},
{id:3, name:'Peter', type:'user', username:'pete'},
{id:4, name:'Bobby', type:'user', username:'be_bob'}
];
var result2 = [
{id:2, name:'John', email:'[email protected]'},
{id:4, name:'Bobby', email:'[email protected]'}
];
var props = ['id', 'name'];
var result = result1.filter(function(o1){
// filter out (!) items in result2
return !result2.some(function(o2){
return o1.id === o2.id; // assumes unique id
});
}).map(function(o){
// use reduce to make objects with only the required properties
// and map to apply this to the filtered array as a whole
return props.reduce(function(newo, name){
newo[name] = o[name];
return newo;
}, {});
});
document.body.innerHTML = '<pre>' + JSON.stringify(result, null, 4) +
'</pre>';
Ответ 2
Тот же результат может быть достигнут с помощью Lodash.
var result1 = [
{id:1, name:'Sandra', type:'user', username:'sandra'},
{id:2, name:'John', type:'admin', username:'johnny2'},
{id:3, name:'Peter', type:'user', username:'pete'},
{id:4, name:'Bobby', type:'user', username:'be_bob'}
];
var result2 = [
{id:2, name:'John', email:'[email protected]'},
{id:4, name:'Bobby', email:'[email protected]'}
];
var result3 = _(result1)
.differenceBy(result2, 'id', 'name')
.map(_.partial(_.pick, _, 'id', 'name'))
.value();
console.log(result3);
<script src="https://cdn.jsdelivr.net/lodash/4.16.4/lodash.min.js"></script>
Ответ 3
Я много искал решение, в котором я могу сравнить два массива объектов с разными именами атрибутов (что-то вроде левого внешнего соединения). Я придумал это решение. Здесь я использовал Lodash. Я надеюсь, что это поможет вам.
var Obj1 = [
{id:1, name:'Sandra'},
{id:2, name:'John'},
];
var Obj2 = [
{_id:2, name:'John'},
{_id:4, name:'Bobby'}
];
var Obj3 = lodash.differenceWith(Obj1, Obj2, function (o1, o2) {
return o1['id'] === o2['_id']
});
console.log(Obj3);
// {id:1, name:'Sandra'}
Ответ 4
Проверьте разницу и xor в lodash.
Ответ 5
Хорошо, это с использованием javascript lodash или vanilla, это зависит от ситуации.
но для того, чтобы просто вернуть массив, содержащий дубликаты, это может быть достигнуто следующим: в конце он был взят из @1983
var result = result1.filter(function (o1) {
return result2.some(function (o2) {
return o1.id === o2.id; // return the ones with equal id
});
});
// if you want to be more clever...
let result = result1.filter(o1 => result2.some(o2 => o1.id === o2.id));
Ответ 6
Вот еще одно решение, использующее Lodash:
var _ = require('lodash');
var result1 = [
{id:1, name:'Sandra', type:'user', username:'sandra'},
{id:2, name:'John', type:'admin', username:'johnny2'},
{id:3, name:'Peter', type:'user', username:'pete'},
{id:4, name:'Bobby', type:'user', username:'be_bob'}
];
var result2 = [
{id:2, name:'John', email:'[email protected]'},
{id:4, name:'Bobby', email:'[email protected]'}
];
// filter all those that do not match
var result = types1.filter(function(o1){
// if match found return false
return _.findIndex(types2, {'id': o1.id, 'name': o1.name}) !== -1 ? false : true;
});
console.log(result);