1

I have two arrays like this:

owners: [
  {
    userID: "58c4d7ac",
    username: "John.Doe",
    firstName: "John",
    lastName: "Doe",
    email: "[email protected]"
  },
  {
    userID: "68c4d7ac",
    username: "User2.Name2",
    firstName: "User2",
    lastName: "Name2",
    email: "[email protected]"
  }
]

users: [
  {
    userID: "58c4d7ac",
    username: "John.Doe",
    firstName: "John",
    lastName: "Doe",
    email: "[email protected]"
  },
  {
    userID: "68c4d7ac",
    username: "User2.Name2",
    firstName: "User2",
    lastName: "Name2",
    email: "[email protected]"
  },
  {
    userID: "88c4d7ac",
    username: "User3.Name3",
    firstName: "User3",
    lastName: "Name3",
    email: "[email protected]"
  }
]

I would like to get an array of users which contains only the elements which are not in the owners array.

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: "[email protected]"
  }
]
0

7 Answers 7

5

You could get rid of your map and just use the filter, (that's exactly what filter is for) somthing like

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

Sign up to request clarification or add additional context in comments.

1 Comment

Worth noting that if performance on large datasets matters to you Shidersz answer below is worth looking at
2

You can use combination of filter and some functions like this:

const owners = [
  {
    userID: "58c4d7ac",
    username: "John.Doe",
    firstName: "John",
    lastName: "Doe",
    email: "[email protected]"
  },
  {
    userID: "68c4d7ac",
    username: "User2.Name2",
    firstName: "User2",
    lastName: "Name2",
    email: "[email protected]"
  }
];

const users = [
  {
    userID: "58c4d7ac",
    username: "John.Doe",
    firstName: "John",
    lastName: "Doe",
    email: "[email protected]"
  },
  {
    userID: "68c4d7ac",
    username: "User2.Name2",
    firstName: "User2",
    lastName: "Name2",
    email: "[email protected]"
  },
  {
    userID: "88c4d7ac",
    username: "User3.Name3",
    firstName: "User3",
    lastName: "Name3",
    email: "[email protected]"
  }
];

const result = users.filter(user => !owners.some(owner => owner.userID === user.userID));

console.log(result);

Comments

2

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.

const owners = [
  {userID: "58c4d7ac", username: "John.Doe", firstName: "John", lastName: "Doe", email: "[email protected]"},
  {userID: "68c4d7ac", username: "User2.Name2", firstName: "User2", lastName: "Name2", email: "[email protected]"}
];

const users = [
  {userID: "58c4d7ac", username: "John.Doe", firstName: "John", lastName: "Doe", email: "[email protected]"},
  {userID: "68c4d7ac", username: "User2.Name2", firstName: "User2", lastName: "Name2", email: "[email protected]"},
  {userID: "88c4d7ac", username: "User3.Name3", firstName: "User3", lastName: "Name3", email: "[email protected]"}
];

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?

In summary, it will improve the performance of the filtering process, particularly if the owners array is large. 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. However, of course, there will be an extra overload at initialization to create the mentioned Set.

Comments

1

You can use filter and some

const owners = [{userID:"58c4d7ac",username:"John.Doe",firstName:"John",lastName:"Doe",email:"[email protected]"},{userID:"68c4d7ac",username:"User2.Name2",firstName:"User2",lastName:"Name2",email:"[email protected]"}]
const users = [{userID:"58c4d7ac",username:"John.Doe",firstName:"John",lastName:"Doe",email:"[email protected]"},{userID:"68c4d7ac",username:"User2.Name2",firstName:"User2",lastName:"Name2",email:"[email protected]"},{userID:"88c4d7ac",username:"User3.Name3",firstName:"User3",lastName:"Name3",email:"[email protected]"}]

const newUsers = users
                .filter(({userID}) => !owners.some(({userID:ownerID})=> ownerID === userID))

console.log(newUsers)

Comments

1

You can just use a single .filter() function, like so:

let owners = [{userID: "58c4d7ac",username: "John.Doe",firstName: "John",lastName: "Doe",email: "[email protected]"},{userID: "68c4d7ac",username: "User2.Name2",firstName: "User2",lastName: "Name2",email: "[email protected]"}];

let users = [{userID: "58c4d7ac",username: "John.Doe",firstName: "John",lastName: "Doe",email: "[email protected]"},{userID: "68c4d7ac",username: "User2.Name2",firstName: "User2",lastName: "Name2",email: "[email protected]"},{userID: "88c4d7ac",username: "User3.Name3",firstName: "User3",lastName: "Name3",email: "[email protected]"}];

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:

Comments

0

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()

 const ownersIds = owners.map(owner => owner.id);
 const diff = users.reduce((acc, user) => { 
   if(!ownersIds.includes(user.id){
     acc.push(user);
    }
    return acc;
     }, []);

Comments

0

You can use the function some or find, this approach uses the function find

let owners = [   {     userID: "58c4d7ac",     username: "John.Doe",     firstName: "John",     lastName: "Doe",     email: "[email protected]"   },   {     userID: "68c4d7ac",     username: "User2.Name2",     firstName: "User2",     lastName: "Name2",     email: "[email protected]"   } ],
    users = [   {     userID: "58c4d7ac",     username: "John.Doe",     firstName: "John",     lastName: "Doe",     email: "[email protected]"   },   {     userID: "68c4d7ac",     username: "User2.Name2",     firstName: "User2",     lastName: "Name2",     email: "[email protected]"   },   {     userID: "88c4d7ac",     username: "User3.Name3",     firstName: "User3",     lastName: "Name3",     email: "[email protected]"   } ],
    result = users.filter(({userID}) => !owners.find(o => o.userID === userID));

console.log(result);
.as-console-wrapper { max-height: 100% !important; top: 0; }

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.