JS比较两个对象数组,将匹配值的元素排除到新数组中
Comparing two arrays of objects, and exclude the elements who match values into new array in 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:'johnny@example.com'},
{id:4, name:'Bobby', email:'bobby@example.com'}
];
var props = ['id', 'name'];
我的目标是让另一个对象数组只包含不匹配的元素。像这样:
var result = [
{id:1, name:'Sandra'},
{id:3, name:'Peter'}
];
我知道有一种方法可以做到这一点,方法是从 result1 开始比较每个对象与 result2 的对象,然后比较它们的键,如果不匹配,将值放在另一个对象中,然后将其推入新数组,但我想知道有没有更优雅的方法,比如使用短划线或下划线或类似的东西。
谢谢!
只需使用 JS 内置的 Array iteration methods 即可:
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:'johnny@example.com'},
{id:4, name:'Bobby', email:'bobby@example.com'}
];
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>';
如果你经常这样做,那么一定要看看外部库来帮助你,但值得先学习基础知识,基础知识在这里会很好地为你服务。
检查 lodash 中的差异和异或。
使用 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:'johnny@example.com'},
{id:4, name:'Bobby', email:'bobby@example.com'}
];
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" 将两个数组之间的差异应用到它们之间的 "link" 元素来获得所需的结果。如果这些属性中的任何一个不同,则元素被认为是不同的(在您的情况下不太可能,因为 id 似乎是唯一的)。
最后,您必须将结果映射到 "omit" 对象的不需要的属性。
希望对您有所帮助。
好吧,这个使用 lodash 或 vanilla javascript 视情况而定。
但对于 return 包含差异的数组可以通过以下方式实现,当然它取自 @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));
我搜索了很多解决方案,在该解决方案中我可以比较具有不同属性名称的两个对象数组(类似于左外连接)。我想出了这个解决方案。这里我使用了 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'}
这是另一个使用 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:'johnny@example.com'},
{id:4, name:'Bobby', email:'bobby@example.com'}
];
// 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);
这是我在 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:'johnny@example.com'},
{id:4, name:'Bobby', email:'bobby@example.com'}
];
var props = ['id', 'name'];
我的目标是让另一个对象数组只包含不匹配的元素。像这样:
var result = [
{id:1, name:'Sandra'},
{id:3, name:'Peter'}
];
我知道有一种方法可以做到这一点,方法是从 result1 开始比较每个对象与 result2 的对象,然后比较它们的键,如果不匹配,将值放在另一个对象中,然后将其推入新数组,但我想知道有没有更优雅的方法,比如使用短划线或下划线或类似的东西。
谢谢!
只需使用 JS 内置的 Array iteration methods 即可:
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:'johnny@example.com'},
{id:4, name:'Bobby', email:'bobby@example.com'}
];
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>';
如果你经常这样做,那么一定要看看外部库来帮助你,但值得先学习基础知识,基础知识在这里会很好地为你服务。
检查 lodash 中的差异和异或。
使用 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:'johnny@example.com'},
{id:4, name:'Bobby', email:'bobby@example.com'}
];
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" 将两个数组之间的差异应用到它们之间的 "link" 元素来获得所需的结果。如果这些属性中的任何一个不同,则元素被认为是不同的(在您的情况下不太可能,因为 id 似乎是唯一的)。
最后,您必须将结果映射到 "omit" 对象的不需要的属性。
希望对您有所帮助。
好吧,这个使用 lodash 或 vanilla javascript 视情况而定。
但对于 return 包含差异的数组可以通过以下方式实现,当然它取自 @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));
我搜索了很多解决方案,在该解决方案中我可以比较具有不同属性名称的两个对象数组(类似于左外连接)。我想出了这个解决方案。这里我使用了 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'}
这是另一个使用 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:'johnny@example.com'},
{id:4, name:'Bobby', email:'bobby@example.com'}
];
// 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);