.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;
}
我想从数组中删除重复项,所以我写了两个 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;
}