I'm sorry I can't speak English well.
These are my simple code with a few parameters array:
if (link.indexOf({"x" : "1" , "y":"2" , "z": "3"}) === -1) {
link.push({
"x": "1",
"y": "2",
"z": "3"
});
} else {
alert("Duplicate");
}
Used in "for" loop but not alert Duplicate.
I'm sorry I can't speak English well.
These are my simple code with a few parameters array:
if (link.indexOf({"x" : "1" , "y":"2" , "z": "3"}) === -1) {
link.push({
"x": "1",
"y": "2",
"z": "3"
});
} else {
alert("Duplicate");
}
Used in "for" loop but not alert Duplicate.
Share Improve this question edited Dec 21, 2019 at 15:13 norbitrial 15.2k10 gold badges39 silver badges64 bronze badges asked Dec 21, 2019 at 15:05 Mersad NilchyMersad Nilchy 6126 silver badges20 bronze badges 4-
1
link.indexOf( {"x" : "1" , "y":"2" , "z": "3"}) === -1
will be always true even if the same looking object is present in array. – Maheer Ali Commented Dec 21, 2019 at 15:09 -
1
Does the
link
array have exactly the same structure of objects? I mean havingx
,y
andz
properties in all? – norbitrial Commented Dec 21, 2019 at 15:12 - Not just to test these numbers manually. How can a key array be prevented from being duplicated? – Mersad Nilchy Commented Dec 21, 2019 at 15:17
- 1 stackoverflow./questions/201183/… – Jeremy J Starcher Commented Dec 21, 2019 at 15:21
4 Answers
Reset to default 2You can create a separate function for this to check if element exists in list or not.
Try this:
function doesExistInList(list, obj) {
for (let i = 0; i < list.length; i++) {
if (list[i].x === obj.x && list[i].y === obj.y && list[i].z === obj.z) {
return true;
}
}
return false;
}
let link = [];
let obj = { "x": "1", "y": "2", "z": "3" };
if (doesExistInList(link, obj) == false) {
link.push(obj);//insert same object to list
} else {
alert("Duplicate");
}
console.log(link);
JavaScript pares objects by reference -- that is, do the two objects point to the exact same spot in memory?
If so, then not only are they equal -- but they are the exact same object.
What you want is a pare-by-value
-- and you'll have to do that yourself.
(You could also use the find
method, but that isn't quite as supported.)
const link = [];
const testVal = {
"x": "1",
"y": "2",
"z": "3"
};
const results = link.filter(k =>
k.x === testVal.x &&
k.y === testVal.y &&
k.z === testVal.z);
if (results.length === 0) {
link.push(testVal);
} else {
alert("Duplicate");
}
console.log(link);
If two objects have same keys and same values in javascript they are different objects. To pare two objects you need to create separate function. Then use some()
to pare each object in array with given object
Note: The below doesn't work for nested object. But it will work for your given case
function pareObjs(a, b){
if(Object.keys(a).length === Object.keys(b).length){
for(let k in a){
if(a[k] !== b[k]){
return false;
}
}
}
else{
return false;
}
return true;
}
const obj = {
"x": "1",
"y": "2",
"z": "3"
}
if(!link.some(a => pareObjs(obj, a))) {
link.push(obj);
} else {
alert("Duplicate");
}
There are couple of options to do that. The issue is with your code even if it looks like you are trying to check with indexOf
if the array contains the targeted object. The main issue is it does not check the values of the properties but the reference of the original object.
So the first solution is, checking each property of the object in a hard coded way if you have the same structure for your object:
const links = [
{x: '2', y: '3', z: '1'},
{x: '11', y: '32', z: '73'},
{x: '1', y: '2', z: '3'},
{x: '93', y: '6', z: '76'},
];
const aim = {x: '1', y: '2', z: '3'};
links.forEach(link => {
const result = link.x === aim.x && link.y === aim.y && link.z === aim.z;
console.log(link, `This object has same property values as aim: ${result}`);
});
There are smarter solutions, just like getting the keys
of the object what it has dynamically and paring them by using some()
:
const links = [
{x: '2', y: '3', z: '1'},
{x: '11', y: '32', z: '73'},
{x: '1', y: '2', z: '3'},
{x: '93', y: '6', z: '76'},
];
const aim = {x: '1', y: '2', z: '3'};
links.forEach(link => {
const keysOfLink = Object.keys(link);
const keysOfAim = Object.keys(aim);
const result = keysOfLink.length === keysOfAim.length &&
keysOfLink.some(key => link[key] === aim[key]);
console.log(link, `This object has same property values as aim: ${result}`);
});
I would go with the second option, that's definitely smartest way to check.
From Array.prototype.some()
's documentation:
The some() method tests whether at least one element in the array passes the test implemented by the provided function. It returns a Boolean value.
Once in the result
variable you have true
value, you can push
as you wanted originally.
I hope this helps!