2015-10-06 40 views
11

匹配值到新的数组中的元素,这里是我的用例中的JavaScript:比较对象的两个数组,并排除谁在JS

我有有匹配(ID &名)属性的对象的两个数组。

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的对象中的每个对象,然后比较他们的钥匙,如果did'n匹配,使这些值按另一对象,然后将它推入新数组中,但我不知道是否有更优雅的方式,例如使用lo-dash或下划线或类似的东西。

谢谢!

+0

分享你的研究可以帮助大家。告诉我们你试过了什么,以及它为什么不符合你的需求。这表明你已经花时间去尝试帮助自己,它使我们避免重申明显的答案,最重要的是它可以帮助你得到更具体和相关的答案!另请参阅[如何问](http://stackoverflow.com/questions/how-to-ask) – Cerbrus

+0

自己探索:[1](http://underscorejs.org/#arrays),[2](https ://lodash.com/docs)。 – hindmost

+0

试试这个:http://stackoverflow.com/questions/368280/javascript-hashmap-equivalent –

回答

21

只是用Array iteration methods内置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>';

如果你这样做了很多,然后通过各种手段来看看外部库来帮助你,但首先需要学习基础知识,基础知识将在这里很好地为您服务。

7

使用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”和“名”的方式在它们之间进行“链接”的元素将两个阵列之间的差异所期望的结果。如果这些属性中的任何一个不同,则这些元素会被认为是不同的(因为id似乎是唯一的,所以在您的情况下不可能)。

最后,您必须映射结果以便“省略”对象的不需要的属性。

希望它有帮助。

1

好吧,这使用lodash或香草javascript这取决于情况。

但只返回一个包含它可以通过以下操作来实现的重复,offcourse它是从@ 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)); 
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'} 
+0

简单而整洁的答案! –

0

下面是使用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);