简体   繁体   English

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

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

I want to remove duplicates from an array, so I wrote code with two for loops.我想从数组中删除重复项,所以我用两个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);

I want to avoid, that the results match twice.我想避免,结果匹配两次。 For example:例如:

result 1: banana & apple结果 1:香蕉和苹果

result 2: apple & banana结果 2:苹果和香蕉

That's why I want top splice the match from ArrayCopy.这就是为什么我想要从 ArrayCopy 顶部拼接匹配。

Before the loop starts the length of MainArray and ArrayCopy are both 4, but after the loop both arrays length are 2.在循环开始之前 MainArray 和 ArrayCopy 的长度都是 4,但循环之后两个数组的长度都是 2。

Why does the length of MainArray change?为什么 MainArray 的长度会发生变化?

The second array is the same object as the original array.第二个数组是与原始数组相同的对象。 To copy the array, you need to create a new array, and append the new array with the items from the first array.Below we use the spread operator to fill a new array with all the values from the main array.要复制数组,您需要创建一个新数组,并将第一个数组中的项附加到新数组中。下面我们使用扩展运算符将主数组中的所有值填充到新数组中。

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

You can also use the slice method to return an array of all the items by not passing any parameters.您还可以使用slice方法通过不传递任何参数来返回所有项目的数组。

const clone = originalArray.slice()

arrays are passed by reference.数组是通过引用传递的。 Which means if you change the copy, the original will change as well.这意味着如果您更改副本,原件也会更改。 if you want a clone of your original array, do this:如果您想要原始数组的克隆,请执行以下操作:

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

The reason this happens is that you are actually storing the first array in the second variable, so you aren't storing another array in there but a reference to the value of the first variable if that makes sense.发生这种情况的原因是您实际上将第一个数组存储在第二个变量中,因此您不是在其中存储另一个数组,而是在有意义的情况下存储对第一个变量的值的引用。

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

Currenty, ArrayCopy references the same memory as MainArray . Currenty, ArrayCopy引用相同的内存MainArray As a result, changing ArrayCopy also changes MainArray (since they refer to the same thing).因此,改变ArrayCopy也会改变MainArray (因为它们指的是同一个东西)。 This is typically referred to as "pointer aliasing", and is often the source of tricky bugs (as you've discovered).这通常称为“指针别名”,并且通常是棘手错误的来源(如您所见)。

Here's an analogy that might help: if Jones has a brother named Steve, then "Jones' brother" and "Steve" both refer to the same person, even though they're different phrases.这里有一个可能有帮助的类比:如果琼斯有一个叫史蒂夫的兄弟,那么“琼斯的兄弟”和“史蒂夫”都是指同一个人,即使它们是不同的短语。 If you deposit $100 into "Steve's" bank account, you've also just deposited $100 into "Jones' brother's" bank account (because they're the same person).如果您将 100 美元存入“史蒂夫”的银行账户,那么您也将 100 美元存入“琼斯兄弟”的银行账户(因为他们是同一个人)。

In general, it's much easier to use functions that don't mutate their arguments.一般来说,使用不改变其参数的函数要容易得多。 Here's a version of removeDuplicates that produces a new array.这是一个生成新数组的removeDuplicates版本。 The strategy is fairly similar to the one you've used above, except it allocates and returns a new array:该策略与您上面使用的策略非常相似,除了它分配并返回一个新数组:

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM