gpt4 book ai didi

javascript - 消除多个数组的重复项

转载 作者:行者123 更新时间:2023-12-03 11:23:07 30 4
gpt4 key购买 nike

我有 3 个数组:

array1 = [ 'A', 'B', 'A', 'B']
array2 = [ 5, 5, 7, 5]
array3 = [true,true,true,true]

我想知道是否有任何简单的方法(可能使用 lodash)来消除重复项并以此结束:

array1 = [ 'A', 'B', 'A']
array2 = [ 5, 5, 7]
array3 = [true,true,true]

我知道我可以执行一个函数并比较之前的值,但是有没有更聪明的方法来做到这一点?

更新请注意,我不需要消除每个数组的重复项。我寻找的是一种“垂直”消除重复项的方法

更新 2请注意,每个“列”都是一条记录。
记录 1 = ['A',5,true]
记录 2 = ['B',5,true]
record3 = ['A',7,true]
记录 1 = ['B',5,true]

最佳答案

长话短说

const records = array1.map((a, i) => [a, array2[i], array3[i]]);

const index = {};
records.filter(column => {
const key = JSON.stringify(column);
return key in index ? false : index[key] = true;
});

嗯?

有很多方法可以解决这个问题,效率各不相同,最佳解决方案将取决于您的数据大小。一个简单但幼稚的解决方案迭代每个“列”并检查所有前面的列是否相等。它看起来像这样:

const array1 = [ 'A', 'B', 'A', 'B'];
const array2 = [ 5, 5, 7, 5];
const array3 = [true,true,true,true];

const newArray1 = array1.slice(0,1); // column 0 is never duplicate
const newArray2 = array2.slice(0,1);
const newArray3 = array3.slice(0,1);

// loop over columns starting with index 1
outer: for (let i = 1; i < array1.length; i++) {
const a = array1[i];
const b = array2[i];
const c = array3[i];

// check all preceding columns for equality
for (let j = 0; j < i; j++) {
if (a === array1[j] && b === array2[j] && c === array3[j]) {
// duplicate; continue at top of outer loop
continue outer;
}
}

// not a duplicate; add to new arrays
newArray1.push(a);
newArray2.push(b);
newArray3.push(c);
}

console.log(newArray1);
console.log(newArray2);
console.log(newArray3);
.as-console-wrapper{min-height:100%}

如您所见,我们每次都必须检查每一列中的每一行是否相等。如果您好奇的话,它的复杂度是 𝑂(𝑛(𝑛+1)/2)(技术上是 𝑂(𝑚𝑛(𝑛+1)/2),其中 𝑚 是三列的 3)。

对于更大的数据集,跟踪您已经在可快速访问的数据结构中看到的值是有利的:散列,也称为 JavaScript 对象。由于您的所有值都是原始值,因此构造键的快速方法是 JSON.stringify。有些人可能认为这是一个“hack”——重要的是要注意它会失败,因为值不能用 JSON 表示,例如InfinityNaN — 但对于如此简单的数据,这是一个快速而简单的方法。

const array1 = ['A', 'B', 'A', 'B'];
const array2 = [5, 5, 7, 5];
const array3 = [true, true, true, true];

const newArray1 = [];
const newArray2 = [];
const newArray3 = [];

const index = {};

for (let i = 0; i < array1.length; i++) {
const a = array1[i];
const b = array2[i];
const c = array3[i];
const key = JSON.stringify([a,b,c]);

if (key in index) {
// duplicate; skip to top of loop
continue;
}

// not a duplicate; record in index and add to new arrays
index[key] = true;
newArray1.push(a);
newArray2.push(b);
newArray3.push(c);
}

console.log(newArray1);
console.log(newArray2);
console.log(newArray3);
.as-console-wrapper{min-height:100%}

它的复杂度是 𝑂(𝑛),或者可能是 𝑂(2𝑚𝑛),其中 𝑚,再次, 三列是 3,而 2 是另一个𝑚,非常粗略地说明了 JSON.stringify 的成本。 (计算哈希访问的成本留给我们中间的 Nerd 练习;我很乐意称它为 𝑂(1)。)

这仍然很冗长。部分原因是对数据使用三个不同的变量(实际上是一个“表格”)会导致大量重复。我们可以对数据进行预处理,使其更容易处理。一旦它被“转置”成一个二维数组,我们就可以使用 Array.prototype.filter 和上面的关键技术,以获得一些非常简洁的代码:

const array1 = ['A', 'B', 'A', 'B'];
const array2 = [5, 5, 7, 5];
const array3 = [true, true, true, true];

// turn "columns" into "rows" of a 2D array
const records = array1.map((a, i) => [a, array2[i], array3[i]]);

const index = {};
const newData = records.filter(column => {
const key = JSON.stringify(column);
return key in index ? false : index[key] = true;
});

console.log(newData);
.as-console-wrapper{min-height:100%}

当然,预处理不是免费的,所以这段代码并不比更冗长的版本更高效;你必须决定这对你有多重要。如果您愿意,现在可以将 newData 中的列提取到三个变量中 (newData.forEach(([a,b,c]) => { newArray1.push(a); newArray2. push(b);/* ... */})), 但对于许多用途而言,“转置”二维数组将更易于使用。

关于javascript - 消除多个数组的重复项,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44331186/

30 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com