Reputation: 67
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?
Upvotes: 1
Views: 759
Reputation: 822
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");
}
Upvotes: 4
Reputation: 10892
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');
}
Upvotes: 3
Reputation: 16908
This is because you are trying to compare 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 comparison. 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 comparison 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 compare 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 compare 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"}'));
Upvotes: 0
Reputation: 186
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
}
Upvotes: 1
Reputation: 101
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')
}
Upvotes: 0
Reputation: 381
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');
}
Upvotes: 2
Reputation: 7106
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 compare the object, e.g.
array.some(e => e.name == newName.name)
Upvotes: 3