Массив массивов в массив уникальных значений с использованием Reduce / Map - PullRequest
0 голосов
/ 25 апреля 2018

У меня есть массив массивов, который должен стать 1 массивом уникальных значений.

[1, 3, 2], [5, 2, 1, 4], [2, 1]

Я хочу использовать Reduce / Map для решения проблемы, но, похоже, она не работает,Я уже решил проблему с помощью вложенных циклов следующим образом:

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;
} 

Теперь я попытался решить эту проблему с помощью метода limit / 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;
      }
    });
  });
}

Я предполагаю, что я что-то не так делаю с операторами возврата в функциях обратного вызова,Любая помощь будет оценена, спасибо.

Ответы [ 2 ]

0 голосов
/ 25 апреля 2018

Вместо использования 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);
0 голосов
/ 25 апреля 2018

Проблема в том, что:

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