使用reduce删除相似的元素

时间:2016-11-07 23:38:41

标签: javascript

https://www.freecodecamp.com/challenges/sorted-union

编写一个带有两个或更多数组的函数,并按照原始提供的数组的顺序返回一个新的唯一值数组。

我已用此代码解决了这个问题:

function uniteUnique(arr) {
  var arg = arguments[0];
  var newArr = [];
  var i = 0;
  var matchFound = false;  

  //start newArr with each element of arg
  while(i < arg.length){
    newArr.push(arg[i++]);
  }

  //iterate over the argument sets
  for(i = 1; i < arguments.length; i++){
    //iterate over the argument set values
    for(var j = 0; j < arguments[i].length; j++){
      //compare each value with arg values 
      for(var k = 0; k < arg.length; k++){
        if(arg[k] === arguments[i][j]){
          matchFound = true;
        }
      }
      if(!matchFound){
        //if no comparison was found add element to newArr
        newArr.push(arguments[i][j]);
      }
      //reset matchFound 
      matchFound = false;
     }
  }

  return newArr;
}

// Function Call
uniteUnique([1, 3, 2], [5, 2, 1, 4], [2, 1]); //returns [1, 3, 2, 5, 4]

我的问题是我如何使用.reduce解决这个问题,还有其他方法可以清理一下以使其更容易阅读吗?

6 个答案:

答案 0 :(得分:1)

只是提供一个选项,因为数据很大,我们不想创建一个大数组并将其过滤掉。

&#13;
&#13;
function uniteUnique(arr) {
    var result = [].concat.apply(arguments[0]);

    for(var i = 1; i < arguments.length; i++) {    
        for(var j = 0; j < arguments[i].length; j++) {
            if (result.indexOf(arguments[i][j]) === -1) {
                result.push(arguments[i][j]);
            }
        }
    }
    return result;
}
    
// Function Call
console.log(uniteUnique([1, 3, 2], [5, 2, 1, 4], [2, 1])); //returns [1, 3, 2, 5, 4]
&#13;
&#13;
&#13;

答案 1 :(得分:0)

console.log(
	(function() {
		return Array.prototype.concat.apply([], arguments)
		.reduce(function(accumulator, iterand) {
			return accumulator.indexOf(iterand) === -1
			? accumulator.concat(iterand)
			: accumulator
		}, []);
	})([1, 3, 2], [5, 2, 1, 4], [2, 1])
);

答案 2 :(得分:0)

您可以将reducefilter合并。

var uniteUnique = [[1, 3, 2], [5, 2, 1, 4], [2, 1]]
.reduce( (a, b) => {
  return a.concat(b)
})
.filter( (x, idx, arr) => arr.indexOf(x) == idx )

console.log(uniteUnique)

但实际上根本没有必要使用reduce。

你可以

var uniteUnique = [1, 3, 2].concat([5, 2, 1, 4], [2, 1])
    .filter( (x, idx, arr) => arr.indexOf(x) == idx )

console.log(uniteUnique)

答案 3 :(得分:0)

你可以迭代数组并读取值并更新输出,如果输出中已经不存在。

let inputArrays = [[1, 3, 2], [5, 2, 1, 4], [2, 1]]
let outputArray = [];
inputArrays.forEach((array) => {
  array.forEach((value) => {
    if(!outputArray.includes(value)){
      outputArray.push(value);
    }
  })
});

console.log(outputArray);

答案 4 :(得分:0)

使用reduce而不首先创建大数组的一种方法就像Will已经完成的:假设第一个数组没有重复并迭代其他数组,添加不在整理数组中的成员。

我使用 Array.from 来创建一个参数数组,但你也可以这样做:

return [].reduce.call(arguments, ...)

function uniteUnique() {
  return Array.from(arguments).reduce(function(a, b) {
    b.forEach(function(v) {
      if (a.indexOf(v) == -1) a.push(v);
    });
    return a;
  },[]); 
}

console.log(uniteUnique([1, 3, 2], [5, 2, 1, 4], [2, 1]));

这是一个箭头功能版本,但我认为它不会节省太多:

function uniteUnique() {
  return Array.from(arguments).reduce((a, b) => {
    b.forEach(v => {if (a.indexOf(v) == -1) a.push(v)});
    return a;
  },[]); 
}

console.log(uniteUnique([1, 3, 2], [5, 2, 1, 4], [2, 1]));

答案 5 :(得分:0)

使用Result: 从参数创建一个来自的数组数组。

[].slice.call(arguments)

然后使用function f(arr1, arr2, arr3) { var arrays = [].slice.call(arguments); // [arr1, arr2, arr3] } 遍历包含reduce()统一的数组的数组。从Array.from()返回一个Set()的数组。

concat()只允许使用唯一值。

总计

Set()

<强>紧凑

var a = [1, 3, 2],
  b = [5, 2, 1, 4],
  c = [2, 1],
  d = [9, 3];

function uniteUnique(arrays) {
  var arrays = [].slice.call(arguments), // An array with arrays
    array = arrays.reduce((a, b) => { // Go throug array with arrays
      return a.concat(b); // to concat them
    })
  return Array.from(new Set(array)); // Create array from Set; Set only has unique values!
}

var r = uniteUnique(a, b, c, d);
console.log(r);