如果我有以下数组:
var myArr = [[0, 1, 2], [1, 2, 6], [9, 10], [10, 11], [11, 12], [13]];
如何合并至少共享一个公共(public)值的数组以产生以下输出?
var myMergedArr = [[0, 1, 2, 6], [9, 10, 11, 12], [13]];
谢谢!
注意:它们并不总是被很好地排序,并且当所有内容都被排序时,共享值可能并不总是开始/结束值。为了清楚起见,我已经订购了上述值。
最佳答案
可以使用空数组(合并
)作为起始值来缩减数组。对于 myArray
中的每个数组,existing
被定义为 merged
的 subArray
数组,使得每个 subArray
和 array
都不为空。
如果找不到这样的数组,existing
将保持未定义状态,并且一个新数组(包含在另一个数组中)将被定义为 existing
并推送到 合并
。
如果找到多个匹配项(existing.slice(1)
不为空),则需要将它们合并在一起:existing[0]
充当容器,其中所有其他子数组(existing[1..]
)被合并(没有重复项)。然后,需要在 merged
中找到这些进一步的匹配项并将其删除,因为它们已经被合并了。这保证了多个数组如果属于在一起就会被合并,即使它们之前没有合并。
然后,array
中的每一项(如果尚未包含)都会被推送到 existing[0]
中。最后,返回merged
。然后 reduce
的下一次迭代可以再次将 merged
作为第一个参数,并继续处理 myArr
中的下一个数组。
这是 ES6 代码。如果需要,您可以将其转译并填充到 ES5。
var myArr = [
[0, 1, 2],
[1, 2, 6],
[9, 10],
[10, 11],
[11, 12],
[13]
],
myMergedArr = myArr.reduce((merged, array) => {
let existing = merged.filter((subArray) => subArray.filter((subItem) => array.includes(subItem)).length);
if (!existing.length) {
existing = [
[]
];
merged.push(existing[0]);
}
else {
existing.slice(1).forEach((furtherArray) => {
furtherArray.forEach((item) => {
if (!existing[0].includes(item)) {
existing[0].push(item);
}
});
merged.splice(merged.findIndex((subArray) => furtherArray == subArray), 1);
});
}
array.forEach((item) => {
if (!existing[0].includes(item)) {
existing[0].push(item);
}
});
return merged;
}, []);
console.log(myMergedArr);
第二个片段是相同的代码,但数组已更改。这是为了证明即使子数组不按顺序排列,此脚本也能正常工作:首先 [0, 1, 2]
独立,然后 [3, 4 , 5]
也是独立的 — 两者仍然分开。仅稍后 [2, 3]
才会导致所有先前的数组合并为一个。
var myArr = [
[0, 1, 2],
[3, 4, 5],
[2, 3],
[7, 9],
[9, 10],
[13]
],
myMergedArr = myArr.reduce((merged, array) => {
let existing = merged.filter((subArray) => subArray.filter((subItem) => array.includes(subItem)).length);
if (!existing.length) {
existing = [
[]
];
merged.push(existing[0]);
}
else {
existing.slice(1).forEach((furtherArray) => {
furtherArray.forEach((item) => {
if (!existing[0].includes(item)) {
existing[0].push(item);
}
});
merged.splice(merged.findIndex((subArray) => furtherArray == subArray), 1);
});
}
array.forEach((item) => {
if (!existing[0].includes(item)) {
existing[0].push(item);
}
});
return merged;
}, []);
console.log(myMergedArr);
关于javascript - JS - 合并至少共享一个共同值的数组,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39552694/