it-swarm.com.ru

Сравнение двух массивов объектов и исключение элементов, которые соответствуют значениям, в новый массив в JS

вот мой вариант использования в JavaScript:

У меня есть два массива объектов, свойства которых совпадают (идентификатор и имя).

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'}
];

Я знаю, что есть способ сделать это, перейдя из result1, сравнить каждый объект с объектами result2, затем сравнить их ключи, и, если они не совпадают, поместить значения в другой объект, затем перенести его в новый массив, но я Интересно, есть ли какой-нибудь более изящный способ, например, использование lo-dash, подчеркивания или чего-то подобного.

Спасибо!

20
Leo

Для этого достаточно использовать методы итерации Array , встроенные в 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>';

Если вы делаете это много, то во что бы то ни стало посмотрите на внешние библиотеки, чтобы помочь вам, но сначала стоит изучить основы, и основы здесь вам пригодятся.

33
1983

ну, это с использованием lodash или Vanilla Javascript, это зависит от ситуации.

но для простого возврата массива, содержащего дубликаты, это может быть достигнуто с помощью следующего, конечно, взято из @ 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));
19
blackend

Тот же результат может быть достигнут с помощью 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>

Вы можете получить желаемый результат, применяя разницу между обоими массивами, используя свойства "id" и "name" как способ "связать" элементы между ними. Если какое-либо из этих свойств отличается, элементы считаются разными (в вашем случае это маловероятно, поскольку id кажется уникальным).

Наконец, вы должны отобразить результат, чтобы «пропустить» нежелательные свойства объекта.

Надеюсь, поможет.

10
acontell

Я много искал решение, в котором я могу сравнить два массива объектов с разными именами атрибутов (что-то вроде левого внешнего соединения). Я придумал это решение. Здесь я использовал 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'}
7
apurvasharma

Проверьте разницу и xor в lodash.

2
jedierikb

Вот еще одно решение с использованием 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);
0
Prasad Thammineni