.splice() 从两个数组中删除项目 - 从数组中删除重复项

.splice() removes item from two arrays - delete duplicates from array

我想从数组中删除重复项,所以我写了两个 for 循环的代码。

let MainArray = [{
            "name": "banana",
            "lat": 3,
            "lng": 3
        },
        {
            "name": "apple",
            "lat": 3,
            "lng": 3
        },
        {
            "name": "car",
            "lat": 1,
            "lng": 1
        },
        {
            "name": "bike",
            "lat": 1,
            "lng": 1
        }
    ];

    let ArrayCopy = MainArray;

    console.log(MainArray.length);
    console.log(ArrayCopy.length);

    for (let i = 0; i < MainArray.length; i++) {

        for (let x = 0; x < ArrayCopy.length; x++) {

            if ((MainArray[i].name !== ArrayCopy[x].name) && ((MainArray[i].lat === ArrayCopy[x].lat) || (MainArray[i].lng === ArrayCopy[x].lng))) {

                //some output

                ArrayCopy.splice(x, 1);
            }
        }
    }

    console.log(MainArray.length);
    console.log(ArrayCopy.length);

我想避免结果匹配两次。例如:

结果 1:香蕉和苹果

结果 2:苹果和香蕉

这就是为什么我要顶部拼接来自 ArrayCopy 的匹配项。

在循环开始之前,MainArray 和 ArrayCopy 的长度都是 4,但是在循环之后,两个数组的长度都是 2。

为什么MainArray的长度会改变?

第二个数组与原始数组是同一个对象。要复制数组,您需要创建一个新数组,并将第一个 array.Below 中的项目追加到新数组中,我们使用展开运算符将主数组中的所有值填充到一个新数组中。

let MainArray = [{
            "name": "banana",
            "lat": 3,
            "lng": 3
        },
        {
            "name": "apple",
            "lat": 3,
            "lng": 3
        },
        {
            "name": "car",
            "lat": 1,
            "lng": 1
        },
        {
            "name": "bike",
            "lat": 1,
            "lng": 1
        }
    ];

    let ArrayCopy = [...MainArray];

    console.log(MainArray.length);
    console.log(ArrayCopy.length);

    for (let i = 0; i < MainArray.length; i++) {

        for (let x = 0; x < ArrayCopy.length; x++) {

            if ((MainArray[i].name !== ArrayCopy[x].name) && ((MainArray[i].lat === ArrayCopy[x].lat) || (MainArray[i].lng === ArrayCopy[x].lng))) {

                //some output

                ArrayCopy.splice(x, 1);
            }
        }
    }

    console.log(MainArray.length);
    console.log(ArrayCopy.length);

您还可以使用 slice 方法 return 不传递任何参数的所有项目的数组。

const clone = originalArray.slice()

数组通过引用传递。这意味着如果您更改副本,原件也会更改。如果您想要原始数组的克隆,请执行以下操作:

let MainArray = [{
            "name": "banana",
            "lat": 3,
            "lng": 3
        },
        {
            "name": "apple",
            "lat": 3,
            "lng": 3
        },
        {
            "name": "car",
            "lat": 1,
            "lng": 1
        },
        {
            "name": "bike",
            "lat": 1,
            "lng": 1
        }
    ];

    let ArrayCopy = JSON.parse(JSON.stringify(MainArray));

    console.log(MainArray.length);
    console.log(ArrayCopy.length);

    for (let i = 0; i < MainArray.length; i++) {

        for (let x = 0; x < ArrayCopy.length; x++) {

            if ((MainArray[i].name !== ArrayCopy[x].name) && ((MainArray[i].lat === ArrayCopy[x].lat) || (MainArray[i].lng === ArrayCopy[x].lng))) {

                //some output

                ArrayCopy.splice(x, 1);
            }
        }
    }

    console.log(MainArray.length);
    console.log(ArrayCopy.length);

发生这种情况的原因是您实际上将第一个数组存储在第二个变量中,因此您没有在其中存储另一个数组,而是对第一个变量的值的引用(如果有意义的话)。

let MainArray = [{
            "name": "banana",
            "lat": 3,
            "lng": 3
        },
        {
            "name": "apple",
            "lat": 3,
            "lng": 3
        },
        {
            "name": "car",
            "lat": 1,
            "lng": 1
        },
        {
            "name": "bike",
            "lat": 1,
            "lng": 1
        }
    ];

   let ArrayCopy = []
   MainArray.forEach((item) => { ArrayCopy.push(item) })


    console.log(MainArray.length);
    console.log(ArrayCopy.length);

    for (let i = 0; i < MainArray.length; i++) {
    

        for (let x = 0; x < ArrayCopy.length; x++) {

            if ((MainArray[i].name !== ArrayCopy[x].name) && ((MainArray[i].lat === ArrayCopy[x].lat) || (MainArray[i].lng === ArrayCopy[x].lng))) {

                //some output

                ArrayCopy.splice(x, 1);
            }
        }
    }
   
    console.log(MainArray.length);
    console.log(ArrayCopy.length);

当前,ArrayCopy 引用 MainArray 相同的内存。因此,更改 ArrayCopy 也会更改 MainArray(因为它们指的是同一事物)。这通常被称为“指针别名”,并且通常是棘手错误的来源(如您所见)。

这里有一个可能有用的类比:如果琼斯有一个名叫史蒂夫的兄弟,那么“琼斯的兄弟”和“史蒂夫”都指的是同一个人,即使它们是不同的短语。如果您将 100 美元存入“史蒂夫”的银行账户,您也刚刚将 100 美元存入“琼斯的兄弟”的银行账户(因为他们是同一个人)。

一般来说,使用不改变参数的函数要容易得多。这是生成新数组的 removeDuplicates 版本。该策略与您在上面使用的策略非常相似,除了它分配并 returns 一个新数组:

function removeDuplicates(xs) {
  // This is a newly allocated array, which we'll fill with the unique elements from `xs`:
  const unique = [];

  for (let x of xs) {
    if (unique.find(y => y.name === x.name && y.lat === x.lat && y.lng === x.lng)) {
      // If we've already seen an element that's equal to `x`, continue.
      continue;
    } else {
      // Otherwise, add it to the output array.
      unique.push(x);
    }
  }

  return unique;
}