admin管理员组

文章数量:1391981

I have an array of objects, and I need to prevent duplicate objects of being added to the array. I've tried the following code to check for duplicates:

const array = [{ name: 'John' }];

const newName = {
  name: 'John'
};
console.log(array);
console.log(newName);

if (array.includes(newName)) {
  console.log(newName.name + ' exists');
} else {
  console.log('name does not exist');
}

Console logging tells that the object NewName is exactly the same as array[0]. However,

if(array.includes(newName))

returns false.

What I'm I doing wrong? I tried the solutions in this post as well with no luck:

How do I check if an array includes an object in JavaScript?

I have an array of objects, and I need to prevent duplicate objects of being added to the array. I've tried the following code to check for duplicates:

const array = [{ name: 'John' }];

const newName = {
  name: 'John'
};
console.log(array);
console.log(newName);

if (array.includes(newName)) {
  console.log(newName.name + ' exists');
} else {
  console.log('name does not exist');
}

Console logging tells that the object NewName is exactly the same as array[0]. However,

if(array.includes(newName))

returns false.

What I'm I doing wrong? I tried the solutions in this post as well with no luck:

How do I check if an array includes an object in JavaScript?

Share Improve this question asked Mar 20, 2019 at 7:12 tekostekos 674 bronze badges 2
  • Possible duplicate of Comparing Arrays of Objects in JavaScript – Mebin Joe Commented Mar 20, 2019 at 7:15
  • Possible duplicate of How to determine if Javascript array contains an object with an attribute that equals a given value? and Typescript : Check if object exist in array by value – adiga Commented Mar 20, 2019 at 7:37
Add a ment  | 

7 Answers 7

Reset to default 4

Simply, you can use array.some from Array.prototype.some() documentation.

In your own example, you can do some tweaks to your program:

const array = [{ name: "John" }];

  const newName = {
    name: "John"
  };
  console.log(array);
  console.log(newName);

  if (array.some(object => object.name === newName.name)) {
    console.log(newName.name + " exists");
  } else {
    console.log("name does not exist");
  }

If the name is the identity of the object, you can use some function on array:

const array = [{ name: 'John' }];    
const newName = { name: 'John' };

if (array.some(({name}) => name === newName.name)) {
  console.log(newName.name + ' exists');
} else {
  console.log('name does not exist');
}

Or you can check if the count of properties is the same and then every property with:

const array = [{ name: 'John', age: 33 }, { name: 'John', age: 45 }];    
const newName = { age: 33, name: 'John' };

if (array.some(x => Object.keys(x).length === Object.keys(newName).length && Object.keys(x).every(p => x[p] === newName[p]))) {
  console.log(newName.name + ' exists');
} else {
  console.log('name does not exist');
}

The thing you're missing is that includes checks for identity when you use it on an object. newName has the same properties as the object in your array, but it isn't the same object any more than two people named John are the same person. For a more obvious example, run {} == {} and you'll get false.

To check if the array contains an object with the same name, you can use some and pass it a function to pare the object, e.g.

array.some(e => e.name == newName.name)

use it :

var newName = {
 name: 'John'
};
console.log(array);
console.log(newName.name);
var found = array.some(obj => obj.name === newName.name);

if (found) {
 console.log(newName.name + ' exists');
} else {
 console.log('name does not exist');
}

const array = [{
  name: 'John'
}];

const newName = {
  name: 'John'
};

let resultArr = array.filter((item) => {
  return item.name === newName.name
})

let elementPresentMsg;

if (resultArr.length > 0) {
  elementPresentMsg = newName.name + ' exists';
} else {
  elementPresentMsg = 'name does not exist'
}

document.getElementById('msg').innerHTML = elementPresentMsg;
<html>

<body>

  <p id="msg"></p>

</body>

</html>

If you want to find the name or any other value from array, if attributes of object are same as that in array of objects, the following should be helpful:

const array = [{ name: 'John' }];

const newName = {
  name: 'John'
};

let resultArr = array.filter((item) => {
    return item.name === newName.name
})

if (resultArr.length > 0) {
  alert(newName.name + ' exists'); //any way to print result instead of alert
} else {
  alert('name does not exist'); //any way to print result instead of alert
}

That is because array[0] not equal newName. In Javascript, they point to the different element. You can try console.log(array[0] == newName), and you will get false.
If you want to find the duplicates, you can try like this:

if (JSON.stringify(array).indexOf(JSON.stringify(newName)) != -1) {
  console.log('exist')
}
else {
  console.log('not exist')
}

This is because you are trying to pare two different instances of objects which will never be equal.

But if you convert the objects to primitive strings by doing JSON.stringify you can then use Array.includes for deep parison. As ttulka pointed out, this will only work if the object to be searched has the properties in the same order as the object to find in the array.

const array = [{ name: 'John', age: 33 }];
const newName = {
  name: 'John',
  age: 33
};
if (array.map(obj => JSON.stringify(obj)).includes(JSON.stringify(newName))) {
  console.log(newName.name + ' exists');
} else {
  console.log('name does not exist');
}

If you look into the Array#includes polyfill in MDN, you would see that the parison happens using the === strict equality operator:

function sameValueZero(x, y) {
   return x === y || (typeof x === 'number' && typeof y === 'number' && isNaN(x) && isNaN(y));
}

// 7. Repeat, while k < len
while (k < len) {
  // a. Let elementK be the result of ? Get(O, ! ToString(k)).
  // b. If SameValueZero(valueToFind, elementK) is true, return true.
  if (sameValueZero(o[k], valueToFind)) {
      return true;
  }
  // c. Increase k by 1. 
  k++;
}

So when you pare two different object literals using === they won't be equal:

console.log({name :"John"} === {name :"John"});

But primitive strings on the other hand are equal if you pare them with ===:

console.log('{name:"John"}' === '{name:"John"}');

But the same is not true for String objects:

console.log(new String('{name:"John"}') === new String('{name:"John"}'));

本文标签: javascriptCheck if array includes a valueStack Overflow