[英]Difference of two javascript arrays of objects
I have two arrays like this: 我有两个像这样的数组:
owners: [
{
userID: "58c4d7ac",
username: "John.Doe",
firstName: "John",
lastName: "Doe",
email: "John.Doe@acme.com"
},
{
userID: "68c4d7ac",
username: "User2.Name2",
firstName: "User2",
lastName: "Name2",
email: "dh@acme.com"
}
]
users: [
{
userID: "58c4d7ac",
username: "John.Doe",
firstName: "John",
lastName: "Doe",
email: "John.Doe@acme.com"
},
{
userID: "68c4d7ac",
username: "User2.Name2",
firstName: "User2",
lastName: "Name2",
email: "dh@acme.com"
},
{
userID: "88c4d7ac",
username: "User3.Name3",
firstName: "User3",
lastName: "Name3",
email: "dh@acme.com"
}
]
I would like to get an array of users which contains only the elements which are not in the owners array. 我想获得一个用户数组,其中只包含不在owners数组中的元素。
I tried different approaches. 我尝试了不同的方法。 Finally, I ended up with the solution:
最后,我得出了解决方案:
const usersItems = users.map(user => {
// Check whether the user is already an owner
if (owners.findIndex(owner => owner.userID === user.userID) === -1) {
return owner
} else {
return null;
}
});
console.log(usersItems);
// Filter out all items which are null
const newUsersItems = usersItems.filter(user => {
if (user) return user;
});
console.log(usersItems);
To me, it doesn't' look like a clean solution. 对我来说,这似乎不是一个干净的解决方案。 Is there a cleaner and easier way to do this?
有没有更清洁,更轻松的方法来做到这一点? As a result, I would like to have:
因此,我希望拥有:
newUsers: [
{
userID: "88c4d7ac",
username: "User3.Name3",
firstName: "User3",
lastName: "Name3",
email: "dh@acme.com"
}
]
You could get rid of your map
and just use the filter, (that's exactly what filter is for) somthing like 您可以摆脱
map
而只需使用过滤器(这正是过滤器的目的)
const filtered = users.filter(user => {
// Check whether the user is already an owner
return owners.findIndex(owner => owner.userID === user.userID) === -1
});
would probably work 可能会工作
First you can create a Set() with the userID's
of the owners
array, and then you can use Array.filter() on the users
array to filter the users whose userID
does not belong to the previous created set. 首先,你可以创建一个集()与
userID's
的的owners
数组,然后你可以使用Array.filter()上的users
阵列筛选其用户的userID
不属于以前创建集。
const owners = [ {userID: "58c4d7ac", username: "John.Doe", firstName: "John", lastName: "Doe", email: "John.Doe@acme.com"}, {userID: "68c4d7ac", username: "User2.Name2", firstName: "User2", lastName: "Name2", email: "dh@acme.com"} ]; const users = [ {userID: "58c4d7ac", username: "John.Doe", firstName: "John", lastName: "Doe", email: "John.Doe@acme.com"}, {userID: "68c4d7ac", username: "User2.Name2", firstName: "User2", lastName: "Name2", email: "dh@acme.com"}, {userID: "88c4d7ac", username: "User3.Name3", firstName: "User3", lastName: "Name3", email: "dh@acme.com"} ]; let ownerIdsSet = new Set(owners.map(x => x.userID)); let res = users.filter(x => !ownerIdsSet.has(x.userID)); console.log(res);
.as-console {background-color:black !important; color:lime;}
But why to construct a Set first?
但是为什么要先构造一个Set?
In summary, it will improve the performance of the filtering process, particularly if the owners
array is large. 总之,它将提高过滤过程的性能,尤其是在
owners
数组很大的情况下。 You should note that methods like findIndex()
, find()
and some()
needs to traverse the array for check to the related condition while checking if the userID
belongs to the Set
is a O(1)
calculation. 您应注意,在检查
userID
属于Set
需要使用findIndex()
, find()
和some()
方法遍历数组以检查相关条件,以进行O(1)
计算。 However, of course, there will be an extra overload at initialization to create the mentioned Set. 但是,当然,在创建上述Set的初始化过程中会产生额外的重载。
You can use combination of filter and some functions like this: 您可以结合使用过滤器和某些功能,例如:
const owners = [ { userID: "58c4d7ac", username: "John.Doe", firstName: "John", lastName: "Doe", email: "John.Doe@acme.com" }, { userID: "68c4d7ac", username: "User2.Name2", firstName: "User2", lastName: "Name2", email: "dh@acme.com" } ]; const users = [ { userID: "58c4d7ac", username: "John.Doe", firstName: "John", lastName: "Doe", email: "John.Doe@acme.com" }, { userID: "68c4d7ac", username: "User2.Name2", firstName: "User2", lastName: "Name2", email: "dh@acme.com" }, { userID: "88c4d7ac", username: "User3.Name3", firstName: "User3", lastName: "Name3", email: "dh@acme.com" } ]; const result = users.filter(user => !owners.some(owner => owner.userID === user.userID)); console.log(result);
You can use filter and some 您可以使用过滤器和一些
const owners = [{userID:"58c4d7ac",username:"John.Doe",firstName:"John",lastName:"Doe",email:"John.Doe@acme.com"},{userID:"68c4d7ac",username:"User2.Name2",firstName:"User2",lastName:"Name2",email:"dh@acme.com"}] const users = [{userID:"58c4d7ac",username:"John.Doe",firstName:"John",lastName:"Doe",email:"John.Doe@acme.com"},{userID:"68c4d7ac",username:"User2.Name2",firstName:"User2",lastName:"Name2",email:"dh@acme.com"},{userID:"88c4d7ac",username:"User3.Name3",firstName:"User3",lastName:"Name3",email:"dh@acme.com"}] const newUsers = users .filter(({userID}) => !owners.some(({userID:ownerID})=> ownerID === userID)) console.log(newUsers)
You can just use a single .filter()
function, like so: 您可以只使用一个
.filter()
函数,如下所示:
let owners = [{userID: "58c4d7ac",username: "John.Doe",firstName: "John",lastName: "Doe",email: "John.Doe@acme.com"},{userID: "68c4d7ac",username: "User2.Name2",firstName: "User2",lastName: "Name2",email: "dh@acme.com"}]; let users = [{userID: "58c4d7ac",username: "John.Doe",firstName: "John",lastName: "Doe",email: "John.Doe@acme.com"},{userID: "68c4d7ac",username: "User2.Name2",firstName: "User2",lastName: "Name2",email: "dh@acme.com"},{userID: "88c4d7ac",username: "User3.Name3",firstName: "User3",lastName: "Name3",email: "dh@acme.com"}]; let newUsersItems = users.filter(user => owners.findIndex(owner => owner.userID === user.userID) === -1); console.log(newUsersItems)
You can just use a single .filter()
function, like so: 您可以只使用一个
.filter()
函数,如下所示:
You can use the reduce function 您可以使用减少功能
const diff = users.reduce((acc, user) => {
if(!owners.find(owner => owner.id === user.id){
acc.push(user);
}
return acc;
}, []);
to avoid use the find() function every loop you can store owner ids in a array with the map an just use includes() 为了避免在每个循环中使用find()函数,您可以将所有者ID与地图一起存储在数组中,而只需使用include()
const ownersIds = owners.map(owner => owner.id);
const diff = users.reduce((acc, user) => {
if(!ownersIds.includes(user.id){
acc.push(user);
}
return acc;
}, []);
You can use the function some
or find
, this approach uses the function find
您可以使用
some
函数或find
函数,这种方法使用find
函数
let owners = [ { userID: "58c4d7ac", username: "John.Doe", firstName: "John", lastName: "Doe", email: "John.Doe@acme.com" }, { userID: "68c4d7ac", username: "User2.Name2", firstName: "User2", lastName: "Name2", email: "dh@acme.com" } ], users = [ { userID: "58c4d7ac", username: "John.Doe", firstName: "John", lastName: "Doe", email: "John.Doe@acme.com" }, { userID: "68c4d7ac", username: "User2.Name2", firstName: "User2", lastName: "Name2", email: "dh@acme.com" }, { userID: "88c4d7ac", username: "User3.Name3", firstName: "User3", lastName: "Name3", email: "dh@acme.com" } ], result = users.filter(({userID}) => !owners.find(o => o.userID === userID)); console.log(result);
.as-console-wrapper { max-height: 100% !important; top: 0; }
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.