web-dev-qa-db-ja.com

オブジェクトの2つの配列を比較し、値が一致する要素をJSの新しい配列に除外します

javaScriptの使用例を次に示します。

プロパティ(id&name)が一致するオブジェクトの2つの配列があります。

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のオブジェクトと比較し、それらのキーを比較し、一致しない場合は別のオブジェクトに値を入れてから新しい配列にプッシュすることでこれを行う方法があることを知っていますロダッシュやアンダースコアなどを使用するなど、もっとエレガントな方法があるのだろうか。

ありがとうございました!

23
Leo

これには、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>';

これを頻繁に行う場合は、必ず外部ライブラリを参照してください。しかし、最初に基本を学ぶ価値があり、基本はここで役立ちます。

38
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));
23
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

異なる属性名(左外部結合のようなもの)を持つ2つのオブジェクトの配列を比較できる解決策をよく探しました。私はこの解決策を思いつきました。ここでは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

Lodashの違いとxorを確認してください。

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);
1