在JavaScript中,我如何检查一个数组是否具有重复的多个值?

3

很抱歉我的英语不好。

以下是我简单的代码和一些参数数组:

 if (link.indexOf({"x" : "1" ,  "y":"2" ,  "z": "3"}) === -1) {
    link.push({
        "x": "1",
        "y": "2",
        "z": "3"
    });    
} else {
    alert("Duplicate");
}

在“for”循环中使用,但不要弹出重复项。


1
link.indexOf( {"x" : "1" , "y":"2" , "z": "3"}) === -1 即使相同的对象存在于数组中,也将始终为真。 - Maheer Ali
1
link 数组的对象结构完全相同吗?我的意思是所有对象都有 xyz 属性吗? - norbitrial
不仅要手动测试这些数字。如何防止键数组被重复? - Mersad Nilchy
1
https://dev59.com/xXVC5IYBdhLWcg3wtzut - Jeremy J Starcher
4个回答

2
您可以创建一个单独的函数来检查列表中是否存在该元素。

请尝试以下代码:

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);


1

JavaScript通过引用比较对象--也就是说,这两个对象是否指向内存中的完全相同的位置?

如果是这样,那么它们不仅相等--而且它们是完全相同的对象。

你想要的是一种按值比较--你必须自己做。

(你也可以使用find方法,但这并不太受支持。)

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);


1

有几种方法可以实现这个目标。问题在于你的代码,即使看起来像是尝试使用 indexOf 检查数组是否包含目标对象,主要问题是它不检查属性值而是原始对象的引用。

因此第一种解决方案是,以硬编码方式检查对象的每个属性,如果对象具有相同的结构:

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}`);
});

有更智能的解决方案,就像获取对象动态的 keys 并使用 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}`);
});

我会选择第二个选项,那绝对是检查的最聪明的方式。 从Array.prototype.some()的文档中可以得知: some() 方法测试是否数组中至少有一个元素通过提供的函数实现的测试。它返回一个布尔值。 一旦变量result 中有了 true 值,你就可以像原来想的那样使用 push 。 希望这能帮到你!

1
如果在JavaScript中两个对象具有相同的键和相同的值,则它们是不同的对象。要比较两个对象,您需要创建一个单独的函数。然后使用some()将数组中的每个对象与给定对象进行比较。 注意:以下内容不适用于嵌套对象。但对于您的情况,它可以工作。
function compareObjs(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 => compareObjs(obj, a))) {
   link.push(obj);
} else {
   alert("Duplicate");
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接