使用reduce从数组中删除重复项

4

我正在尝试从一个数组列表中删除重复项。我尝试的方法是使用reduce创建一个空数组,将所有未定义的索引推入该数组中。但是,我遇到了错误。

if(acc[item]===undefined){
      ^
TypeError: Cannot read property '1' of undefined

以下是我的函数:

function noDuplicates(arrays) {
  var arrayed = Array.prototype.slice.call(arguments);

  return reduce(arrayed, function(acc, cur) {
    forEach(cur, function(item) {
      if (acc[item] === undefined) {
        acc.push(item);
      }
      return acc;
    });
  }, []);
}

console.log(noDuplicates([1, 2, 2, 4], [1, 1, 4, 5, 6]));


console.log(noDuplicates([1,2,2,4],[1,1,4,5,6]));的输出应该是什么? - Ved
[1,2,4,5,6] - learninjs
可能是从JavaScript数组中删除重复项的重复问题。 - Preview
7个回答

9

首先将这两个数组拼接起来,然后使用filter()函数过滤掉重复的元素。

var a = [1, 2, 2, 4], b = [1, 1, 4, 5, 6];
var c = a.concat(b);
var d = c.filter(function (item, pos) {return c.indexOf(item) == pos});
console.log(d);


5
您在调用方法和返回acc的方式上存在一些问题:

function noDuplicates(arrays) {
  var arrayed = Array.prototype.slice.call(arguments);

  // reduce is a method of an array, so call it as a method
  // return reduce(arrayed, function(acc, cur) {
  return arrayed.reduce(function(acc, cur) {
  
    // Same with forEach
    cur.forEach(function(item) {
      if (acc[item] === undefined) {
        acc.push(item);
      }
       // Return acc from the reduce callback, forEach returns undefined always
       // return acc;
    });
    return acc;
  }, []);
}

console.log(noDuplicates([1, 2, 2, 4], [1, 1, 4, 5, 6]));

您可以直接使用call在arguments上调用reduce:
Array.prototype.reduce.call(arguments, function(acc, curr) {
  // ...
});

上述代码可以运行,但是它不能像测试一样产生正确的输出结果。
  if (acc[item] === undefined)

它不能做你想要的事情。你需要做的是记住每个值,并且只有在之前没有出现过时才将其推送到acc中:

function noDuplicates(arrays) {
  var arrayed = Array.prototype.slice.call(arguments);
  var seen = {};

  return arrayed.reduce(function(acc, cur) {
    cur.forEach(function(item) {
      if (!seen[item]) {
        acc.push(item);
        seen[item] = true;
      }
    });
    return acc;
  }, []);
}

console.log(noDuplicates([1, 2, 2, 4], [1, 1, 4, 5, 6]));

一些其他的方法:

// A more concise version of the OP
function noDupes() {
  return [].reduce.call(arguments, function(acc, arr) {
    arr.forEach(function(value) {
      if (acc.indexOf(value) == -1) acc.push(value);
    });
    return acc;
   },[]);
}
 
console.log(noDupes([1, 2, 2, 4], [1, 1, 4, 5, 6]));

// Some ECMAScript 2017 goodness
function noDupes2(...args){
 return [].concat(...args).filter((v, i, arr) => arr.indexOf(v)==i);
}

console.log(noDupes2([1, 2, 2, 4], [1, 1, 4, 5, 6]));


4

我的解决方案是 -

var numbers = [1, 1, 2, 3, 4, 4];

function unique(array){
  return array.reduce(function(previous, current) {
     if(!previous.find(function(prevItem){
         return prevItem === current;
     })) {
        previous.push(current);
     }
     return previous;
 }, []);
}

unique(numbers);

非常有帮助!谢谢您的支持 =) - jonathasborges1

3

为什么要使用reduce?因为我们可以通过先合并这两个数组,然后使用Set来删除重复的键,轻松完成此操作。

请看以下示例:

function noDuplicates(a, b){
    var k = a.concat(b);
    return [...new Set(k)];
}

console.log(noDuplicates([1,2,2,4],[1,1,4,5,6]));

请查看文档,Set 如何工作


使用数组连接有点减弱了使用“Set”的意义,而使用“Set”确实是个好主意。 - Igor Soloydenko

2

为了寻找MDN完全相同问题的更平滑解决方案,我提出了这个解决方案,我认为它简单而美观。我刚刚在MDN上更新了它,并想在这里分享(我对这些东西真的很新,如果做错了什么,对不起)

let myArray = ['a', 'b', 'a', 'b', 'c', 'e', 'e', 'c', 'd', 'd', 'd', 'd'];
var myOrderedArray = myArray.reduce(function (accumulator, currentValue) {
  if (accumulator.indexOf(currentValue) === -1) {
    accumulator.push(currentValue);
  }
  return accumulator
}, [])

console.log(myOrderedArray);

(我刚开始接触这个,希望这会有所帮助)


0
之前的答案并不适用于大型数组。以下方法可以实现线性的O符号表示:

const dedupWithReduce = (arr) =>
  arr.reduce(
    (acc, cur) => {
      if (!acc.lookupObj[cur]) {
        return {
          lookupObj: {
            ...acc.lookupObj,
            [cur]: true
          },
          dedupedArray: acc.dedupedArray.concat(cur)
        };
      } else {
        return acc;
      }
    },
    { lookupObj: {}, dedupedArray: [] }
  ).dedupedArray;


0

使用reduce函数在JS中从数组中删除重复元素

const arr = [1,2,3,4,4,5,5,5,6];

const uniqueArray = (arr) => {
    return arr.reduce((acc,ele) => {
        return acc.includes(ele) ? acc : [...acc,ele]
    },[])
}

console.log(uniqueArray(arr)); // [1,2,3,4,5,6]

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接