如何快速比较数组中的所有元素

时间:2019-08-18 08:05:40

标签: javascript html arrays object html5-canvas

我有一个包含100个元素的字符串,该数组有100个对象。这些对象具有X和y值。我想找到具有相同X和y值的元素。我该怎么办?

 for (var i = 0; i < circleArray.length; ++i) {
                for (var j = 1; j < circleArray.length; ++j)
                    if (circleArray[i].x == circleArray[j].x && circleArray[i].y == circleArray[j].y) {
                        console.log("mission completed");
                    }
            }

我按照上面的方法进行操作,但是它会消耗很多性能并且工作非常缓慢。

所有代码:https://codepen.io/tolgaand/pen/PoYzaKP

5 个答案:

答案 0 :(得分:3)

我们可以使用Set来基于两个属性xy来查看是否遇到重复元素,如果是重复元素,则将其添加到{{1 }}数组:

dup

要删除重复项,我们可以使用const circleArray = [{x: 100, y: 200, c: 30}, {x:50, y:40, c:56}, {x:23, y:78, c:90}, {x:50, y:40, c:78}, {x:23, y:78, c:98}, {x:2, y:378, c:90}, {x:237, y:8, c:10}]; //To get the duplicate objects const seen = new Set(); const dup = circleArray.reduce((acc, obj) => { //if size is same, the object is a duplicate based on x and y props if(seen.size === seen.add(obj.x + "|" + obj.y).size){ acc.push(obj); } return acc; }, []); console.log(dup);根据Array.prototype.filterx属性将重复对象过滤到新数组中:

y

答案 1 :(得分:1)

使用some-一旦找到匹配的对,它将立即停止:

if (circleArray.some(({ x, y }, i) => circleArray.some(({ x: x2, y: y2 }, j) => i != j && x == x2 && y == y2))) {
    console.log("Mission completed!");
}

答案 2 :(得分:0)

您可以在每次迭代中排除相同的项目,以便减少下一个循环的迭代次数。当您没有相同的对象时,最坏的情况就会发生。

            circleArray.splice(j, 1);

完整代码

for (var i = 0; i < circleArray.length; ++i)
{

    for (var j = 1; j < circleArray.length; ++j)
        if (circleArray[i].x == circleArray[j].x && circleArray[i].y == circleArray[j].y)
        {
            console.log("mission completed")
            circleArray.splice(j, 1);
        }
}



答案 3 :(得分:0)

我的理解是删除两个重复项。如果不正确,请说明要求。我看不到OP与链接代码之间的关系,以下内容基于OP中的代码。

一种方法是创建一个值索引,该值引用 circleArray 中相关对象的索引。找到重复项后,它们的索引将添加到删除数组中。 remove 数组被循环以删除所有重复项。这将循环遍历原始数组,并每个数组重复一次。

通过在 remove 数组中的等效索引处插入要删除的索引,逻辑得到简化,删除索引的顺序保持不变,而无需排序,并且 remove 数组保持尽可能小,因此最终的 reduceRight 仅根据需要进行迭代( reduceRight 仅访问存在的元素,例如[,1,,,,5]将仅迭代两次)

let circleArray = [
  {x: 0, y:0},
  {x: 5, y:5},  // dupe
  {x: 1, y:1},
  {x: 2, y:2},  // dupe
  {x: 2, y:2},  // dupe
  {x: 5, y:5},  // dupe
  {x: 3, y:3},  // dupe
  {x: 4, y:4},
  {x: 5, y:5},  // dupe
  {x: 3, y:3},  // dupe
  {x: 6, y:6},
  {x: 5, y:5}   // dupe
];

function removeDupes(arr) {

  // Array of indexes to remove
  let remove = [];

  // Get indexes to remove
  arr.reduce((acc, obj, i) => {

    // Create key from x and y values
    let idx = obj.x + ':' + obj.y;

    // If it's dupe, add it and the initial dupe to the remove array
    if (acc[idx]) {
      remove[i] = i;
      remove[acc[idx].idx] = acc[idx].idx;

    // Otherwise, just add it to the index (don't need dupes in index)
    } else {
      acc[idx] = {idx: i};
    }
    return acc;
  }, Object.create(null));

  // Go backwards over remove and splice dupes
  remove.reduceRight((acc, idx) => circleArray.splice(idx, 1), null);
}

removeDupes(circleArray);

console.log(circleArray)

只有测试才能证明这是否比其他方法更快,并且在不同的实现中不同方法的性能可能会有所不同。

一种更好的方法可能是避免一开始就创建重复项,例如,通过在将值放入 circeArray 时保持索引的值,而不插入重复项。

答案 4 :(得分:0)

我认为您可以使用JavaScript数组方法.map()、. reduce()、. filter()实现此目的。和.find()。 PFB示例代码。

var arrA=[{x:10,y:20},{x:30,y:40},{x:50,y:60}];
var arrB=[{x:12,y:20},{x:21,y:40},{x:51,y:60},{x:50,y:60}];

var result = arrA.map(function (ele, i) {
      var res=arrB.find(function(item, index, array) {
        return (item.x==ele.x && item.y==ele.y) ? (item['j']=index) : null;
      });
      if(res !=null){ res['i']=i;}
      return res;
});
var finalresult= result.filter(item => item !=null);

输出:[{“ x”:50,“ y”:60,“ j”:3,“ i”:2}]