我有一个数组数组,需要成为1个唯一值数组。
[1, 3, 2], [5, 2, 1, 4], [2, 1]
我想使用reduce / map来解决问题,但它似乎并没有起作用。我已经用嵌套for循环解决了这个问题,如下所示:
function uniteUnique(arr) {
var args = Array.from(arguments);
var arr = [];
for (var i = 0; i < args.length; i++) {
for (var j = 0; j < args[i].length; j++) {
if (!arr.includes(args[i][j])) {
arr.push(args[i][j]);
}
}
}
return arr;
}
现在我尝试使用reduce / map解决问题,但没有得到正确的解决方案,如下所示:
function uniteUnique(arr) {
var args = Array.from(arguments);
return args.reduce(
(arr, a) => a.map(n => (!arr.includes(n) ? arr.push(n) : n)),
[]
);
}
console.log(uniteUnique([1, 3, 2], [5, 2, 1, 4], [2, 1]));
我还尝试用reduce / map解决,使用较旧的语法,如下所示:
function uniteUnique(arr) {
var args = Array.from(arguments);
return args.reduce(function(arr, a) {
return a.map(function(n) {
if (!arr.includes(n)) {
return arr.push(n);
} else {
return n;
}
});
});
}
我的猜测是我没有使用回调函数中的return语句做正确的事情。任何帮助将不胜感激,谢谢。
答案 0 :(得分:5)
问题在于:
arr.includes(n)
arr
是一个数组数组,包括不在那里工作。你也永远不会将arr
传递给减少链。
最容易解决的是:
[...new Set(array.reduce((a, b) => a.concat(b), []))]
这只是展平数组,为唯一性构建一个Set并将其传播到一个数组中。或者使用迭代器的另一个优雅的解决方案:
function* flatten(arr) {
for(const el of arr) {
if(Array.isArray(el)) {
yield* flatten(el);
} else {
yield el;
}
}
}
const result = [];
for(const el of flatten(array))
if(!result.includes(el)) result.push(el);
答案 1 :(得分:1)
而不是使用array#map
使用array#forEach
并在累加器中输入唯一编号。
function uniteUnique(arr) {
var args = Array.from(arguments);
return args.reduce((arr, a) => {
a.forEach(n => (!arr.includes(n) ? arr.push(n) : n));
return arr
},[]);
}
console.log(uniteUnique([1, 3, 2], [5, 2, 1, 4], [2, 1]));
或者,您可以array#concat
所有数组,然后使用Set
获取唯一值。
const arr = [[1, 3, 2], [5, 2, 1, 4], [2, 1]],
unique = [...new Set([].concat(...arr))];
console.log(unique);