首页 > 解决方案 > 使用 Reduce/Map 将数组数组转换为唯一值数组

问题描述

我有一个数组数组,需要成为 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;
      }
    });
  });
}

我的猜测是我对回调函数中的返回语句做的不对。任何帮助将不胜感激,谢谢。

标签: javascriptreduce

解决方案


问题是:

 arr.includes(n)

arr是一个数组数组,包括不会在那里工作。你也永远不会传递arrreduce 链。


最容易解决的是:

  [...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);

推荐阅读