1

I have this array of all users:

let allUsers = [
    {
        id: 1,
        name: "Mike"
    },
    {
        id: 2,
        name: "John"
    },
    {
        id: 3,
        name: "Kim"
    },
    {
        id: 4,
        name: "Mike"
    }
];

Now I have array of batches. Each batch has its own users array.

const userBatches = [
    {   
        "batchId": 1,
        "users": [
            {
                id: 5,
                name: "Max"
            },
            {
                id: 2,
                name: "Simon"
            }
        ]
    },
    {   
        "batchId": 2,
        "users": [
            {
                id: 6,
                name: "Max"
            },
            {
                id: 7,
                name: "Conor"
            }
        ]
    },
    {   
        "batchId": 3,
        "users": [
            {
                id: 3,
                name: "Norman"
            }
        ]
    }
]

Here I want to push only those users that does not exists in allUsers array. (on the basis of user id not name)

In simple words allUsers should contain the unique users. No duplicates.

Expected response of allUsers:

[
    {
        id: 1,
        name: "Mike"
    },
    {
        id: 2,
        name: "John"
    },
    {
        id: 3,
        name: "Kim"
    },
    {
        id: 4,
        name: "Mike"
    },
    {
        id: 5,
        name: "Max"
    },
    {
        id: 6,
        name: "Max"
    },
    {
        id: 7
        name: "Conor"
    }
]

Here is the attached code snippet:

let allUsers = [
    {
        id: 1,
        name: "Mike"
    },
    {
        id: 2,
        name: "John"
    },
    {
        id: 3,
        name: "Kim"
    },
    {
        id: 4,
        name: "Mike"
    }
];

const userBatches = [
    {   
        "batchId": 1,
        "users": [
            {
                id: 5,
                name: "Max"
            },
            {
                id: 2,
                name: "Simon"
            }
        ]
    },
    {   
        "batchId": 2,
        "users": [
            {
                id: 6,
                name: "Max"
            },
            {
                id: 7,
                name: "Conor"
            }
        ]
    },
    {   
        "batchId": 3,
        "users": [
            {
                id: 3,
                name: "Norman"
            }
        ]
    }
];

userBatches.forEach((batch) => {
    
  console.log(batch)
    // if batch users does not exists allUsers array then add these users to allUsers array 
});

2
  • You pretty much have solved it yourself with your comment after the .log. JS array some and you got it. Commented Dec 2, 2022 at 8:17
  • yeah I know the concept but I am unable to apply the better approach here, I need a clean and optimized way to achieve this. Commented Dec 2, 2022 at 8:19

4 Answers 4

3

Here’s one possible solution using the array method filter:

const uniqueUsers = userBatches.flatMap(batch => batch.users)
  .filter(user => !allUsers.some(u => u.id === user.id))
  .concat(allUsers);

console.log(uniqueUsers);

// Output: [
// { id: 1, name: 'Mike' },
// { id: 2, name: 'John' },
// { id: 3, name: 'Kim' },
// { id: 4, name: 'Mike' },
// { id: 5, name: 'Max' },
// { id: 6, name: 'Max' },
// { id: 7, name: 'Conor' }
// ]
Sign up to request clarification or add additional context in comments.

1 Comment

Neat solution! I liked this approach as it's readable and clear
0

let allUsers = [{
    id: 1,
    name: "Mike"
  },
  {
    id: 2,
    name: "John"
  },
  {
    id: 3,
    name: "Kim"
  },
  {
    id: 4,
    name: "Mike"
  }
];

const userBatches = [{
    "batchId": 1,
    "users": [{
        id: 5,
        name: "Max"
      },
      {
        id: 2,
        name: "Simon"
      }
    ]
  },
  {
    "batchId": 2,
    "users": [{
        id: 6,
        name: "Max"
      },
      {
        id: 7,
        name: "Conor"
      }
    ]
  },
  {
    "batchId": 3,
    "users": [{
      id: 3,
      name: "Norman"
    }]
  }
];

userBatches.forEach(ub => {
  ub.users.forEach(ubu => {
    if (!allUsers.some(au => au.id === ubu.id)) allUsers.push(ubu)
  })
})

console.log(allUsers);

1 Comment

Can we avoid ub.users.forEach?
0

You can use Array.some() to see if the array has the object by comparing the IDs, as follows:

let allUsers = [{
    id: 1,
    name: "Mike"
  },
  {
    id: 2,
    name: "John"
  },
  {
    id: 3,
    name: "Kim"
  },
  {
    id: 4,
    name: "Mike"
  }
];

const userBatches = [{
    "batchId": 1,
    "users": [{
        id: 5,
        name: "Max"
      },
      {
        id: 2,
        name: "Simon"
      }
    ]
  },
  {
    "batchId": 2,
    "users": [{
        id: 6,
        name: "Max"
      },
      {
        id: 7,
        name: "Conor"
      }
    ]
  },
  {
    "batchId": 3,
    "users": [{
      id: 3,
      name: "Norman"
    }]
  }
];

userBatches.forEach((batch) => {
  batch.users.forEach(user => {
    if (!allUsers.some(u => u.id === user.id)) {
      allUsers.push(user)
    }
  })
});

console.log(allUsers)


Option 2:

If you want to avoid nested Array.forEach(), you can use Array.filter() and the spread operator. But note that this way you are creating a new array in each iteration

let allUsers = [{
    id: 1,
    name: "Mike"
  },
  {
    id: 2,
    name: "John"
  },
  {
    id: 3,
    name: "Kim"
  },
  {
    id: 4,
    name: "Mike"
  }
];

const userBatches = [{
    "batchId": 1,
    "users": [{
        id: 5,
        name: "Max"
      },
      {
        id: 2,
        name: "Simon"
      }
    ]
  },
  {
    "batchId": 2,
    "users": [{
        id: 6,
        name: "Max"
      },
      {
        id: 7,
        name: "Conor"
      }
    ]
  },
  {
    "batchId": 3,
    "users": [{
      id: 3,
      name: "Norman"
    }]
  }
];

userBatches.forEach((batch) => {
  allUsers = [...allUsers, ...batch.users.filter(user => !allUsers.some(u => u.id === user.id))]
});

console.log(allUsers)

2 Comments

any way to avoid batch.users.forEach?
@StormTrooper I added the 2nd option per your request
0

An efficient solution would be to create a map id=>user and populate it from both arrays:

uniqueUsers = [...new Map([
    ...allUsers.map(u => [u.id, u]),
    ...userBatches.flatMap(b => b.users).map(u => [u.id, u])
]).values()];

1 Comment

This is better but I would like foreach to stay as is, since i need to perform insertion to db in foreach

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.