web-dev-qa-db-fra.com

Comparer deux tableaux d'objets et exclure les éléments qui correspondent aux valeurs d'un nouveau tableau dans JS

voici mon cas d'utilisation en JavaScript:

J'ai deux tableaux d'objets dont les propriétés correspondent (id et nom).

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

Mon objectif est d’avoir un autre tableau d’objets contenant uniquement les éléments qui ne correspondent pas. Comme ça:

var result = [
    {id:1, name:'Sandra'},
    {id:3, name:'Peter'}
];

Je sais qu'il existe un moyen de le faire en allant de result1 comparer chaque objet avec les objets de result2, puis comparer leurs clés, et si ne correspond pas, mettre les valeurs dans un autre objet puis le pousser dans un nouveau tableau la merveille existe-t-elle de manière plus élégante, comme utiliser un tiret bas ou un soulignement similaire.

Je vous remercie!

20
Leo

Il suffit d’utiliser les méthodes d’itération Array intégrées à 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>';

Si vous le faites souvent, vous devez certainement vous adresser à des bibliothèques externes pour vous aider, mais cela vaut la peine de commencer par apprendre les bases, et les bases vous seront très utiles ici.

33
1983

eh bien, cela en utilisant lodash ou javascript Vanilla cela dépend de la situation.

mais pour simplement renvoyer le tableau qui contient les doublons, cela peut être réalisé de la manière suivante, hors cours, il a été tiré de @ 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

Le même résultat peut être obtenu avec 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>

Vous pouvez obtenir le résultat souhaité en appliquant une différence entre les deux tableaux en utilisant les propriétés "id" et "name" comme moyen de "lier" des éléments entre eux. Si l'une de ces propriétés est différente, les éléments sont considérés comme différents (de manière improbable dans votre cas car id semble unique).

Enfin, vous devez mapper le résultat pour "omettre" les propriétés indésirables de l'objet.

J'espère que ça aide.

10
acontell

J'ai beaucoup cherché une solution permettant de comparer deux tableaux d'objets portant des noms d'attributs différents (un type de jointure externe gauche). Je suis venu avec cette solution. Ici j'ai utilisé Lodash. J'espère que cela t'aidera. 

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

Découvrez la différence et xor dans lodash.

2
jedierikb

Voici une autre solution utilisant 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