1

I got an array of objects with structure like this

myArr = [
         {name: Test1, age: 20,  info: Test2}, 
         {name: Test2, age: 20, info: Test3},
         {name: Test5, age: 28, info: Test30}
 ]

With my custom action I am adding new info to array. But before adding new obejct into array I want to check if similiar one exist (same values for all keys). If yes - do nothing, if no similar object - add to array.

Simple for loop duplicates objects since it is running over all elements of the array.

var i;
for(i = 0; i < myArr.length; i++) {
    if((myArr[i].name === added.name) && (myArr[i].age === added.age) && (myArr[i].info === added.info) {

    }
    else {
        myArr.push(added);
    }
}
4
  • 1
    Are you OK with using an external library like LoDash (lodash.com)? That has functions for search an array for matching objects. Commented Mar 9, 2018 at 12:17
  • @kshetline: So does the JavaScript standard library (as of three years ago). Commented Mar 9, 2018 at 12:18
  • 1
    @TJ -- Methods that would match each object in an array with another object, member-by-member, rather than doing a simple === comparison? Commented Mar 9, 2018 at 12:24
  • @kshetline: Not that specifically, no, but not far off either. For instance: var keys = Object.keys(added); if (!myArr.some(e => keys.every(k => added[k] === e[k]))) { /* ... */ } Throw in Object.keys(e).length === keys.length if you want that check (or tweak in about 18 other ways). Commented Mar 9, 2018 at 12:56

2 Answers 2

4

The problem is that you're adding within the loop. Instead, you want to add only after the loop if you didn't find a match.

So with minimal changes:

var i;
for(i = 0; i < myArr.length; i++) {
    if((myArr[i].name === added.name) && (myArr[i].age === added.age) && (myArr[i].info === added.info) {
        // Found, stop here
        break;
    }
}
if (i === myArr.length) {
    // Not found, add
    myArr.push(added);
}

But you can also use Array#find (added in ES2015, you can polyfill it for obsolete environments) or Array#some (also added in ES2015):

if (!myArr.find(function(e) { return e.name === added.name && e.age === added.age && e.info === added.info; })) {
    myArr.push(added);
}

It's a bit clearer if you use an ES2015 arrow function:

if (!myArr.find(e => e.name === added.name && e.age === added.age && e.info === added.info)) {
    myArr.push(added);
}
Sign up to request clarification or add additional context in comments.

Comments

0

Check this. You can use .find() to match your condition and check if it is already present.

myArr = [
         {name: 'Test1', age: 20,  info: 'Test2'}, 
         {name: 'Test2', age: 20, info: 'Test3'},
         {name: 'Test5', age: 28, info: 'Test30'}
 ]
 
let added = {name: 'Test6', age: 22, info: 'Test40'};
 
let matching = myArr.find(a => a.name === added.name && a.age === added.age && a.info === added.info);

if(!matching) {
  myArr.push(added)
  console.log('added');
  console.log(myArr)
}

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.