我需要找到传递给函数 union
的三个数组的并集。
我花了大约 50 行代码来获得预期的结果。显然,以下代码有效,但现在我想知道完成相同工作的最佳方法是什么(功能性和非功能性方式)。
function union(...arrays) {
var array1 = arguments[0];
var array2 = arguments[1];
var array3 = arguments[2];
var unique = [];
var intersaction = [];
// find the unique values
for(let i = 0; i < array1.length; i++) {
if( (array2.includes(array1[i]) == false) && (array3.includes(array1[i])) == false ) {
unique.push(array1[i]);
}
}
for(let i = 0; i < array2.length; i++) {
if( (array1.includes(array2[i]) == false) && (array3.includes(array2[i])) == false ) {
unique.push(array2[i]);
}
}
for(let i = 0; i < array3.length; i++) {
if( (array1.includes(array3[i]) == false) && (array2.includes(array3[i])) == false ) {
unique.push(array3[i]);
}
}
// find the intersection
for(let j = 0; j < array1.length; j++) {
if(array2.includes(array1[j]) || array3.includes(array1[j]) ) {
if (intersaction.indexOf(array1[j]) == -1) {
intersaction.push(array1[j]);
}
}
}
for(let j = 0; j < array2.length; j++) {
if(array1.includes(array2[j]) || array3.includes(array2[j]) ) {
if (intersaction.indexOf(array2[j]) == -1) {
intersaction.push(array2[j]);
}
}
}
for(let j = 0; j < array3.length; j++) {
if(array1.includes(array3[j]) || array2.includes(array3[j]) ) {
if (intersaction.indexOf(array3[j]) == -1) {
intersaction.push(array3[j]);
}
}
}
return union = [...intersaction, ...unique];
}
console.log(union([5, 10, 15], [15, 88, 1, 5, 7], [100, 15, 10, 1, 5]));
// should log: [5, 10, 15, 88, 1, 7, 100]
最佳答案
只是保留 OP 提供的原始函数签名的另一种解决方案:
function union(...arrays) {
return Array.from(new Set([...arrays].flat()));
}
console.log(union([5, 10, 15], [15, 88, 1, 5, 7], [100, 15, 10, 1, 5]));
或者,甚至更短(但阅读起来不太友好):
return [...(new Set([...arrays].flat()))];
解释:
Array.from
将 Iterable 作为参数,这将从原始数组创建一个新数组。[...arrays]
将数组(参数)展开为一个新的单个数组(因此它变成了数组的数组)->[5, 10, 15] , [15, 88, 1, 5, 7], [100, 15, 10, 1, 5]
变为:[[5, 10, 15], [15, 88, 1, 5 , 7], [100, 15, 10, 1, 5]]
.flat
将数组展平,使其成为值数组而不是值数组的 ar 数组 -> https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/flat ->[[5, 10, 15], [15, 88, 1, 5, 7], [100, 15, 10, 1, 5]]
变为[5, 10 , 15, 15, 88, 1, 5, 7, 100, 15, 10, 1, 5]
new Set
从数组中删除重复项并返回 Iterable https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Set . ->[5, 10, 15, 15, 88, 1, 5, 7, 100, 15, 10, 1, 5]
成为一个没有重复项的 Set 实例(一个 Iterable)。 Array.from 然后将 Set (Iterable) 转换为常规数组。此处提供更多信息:How to convert Set to Array?
注意:Array.flat
目前是一项实验性功能 (https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/flat)。下面不使用 flat 的解决方案:
function union(...arrays) {
return Array.from(new Set([].concat.apply([],[...arrays])));
}
console.log(union([5, 10, 15], [15, 88, 1, 5, 7], [100, 15, 10, 1, 5]));
解释(仅与上述不同):
- 我们将原始数组应用到
Array.concat
而不是 .flat,这样它将展平它传递一个新数组作为其this
并将我们的数组提供为参数:[].concat.apply([],[...arrays])
片段:http://jsfiddle.net/briosheje/y03osape/2/
没有 .flat
的片段:http://jsfiddle.net/briosheje/y03osape/4/
关于javascript - 三个数组之间的联合,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53794570/