从数组中完全删除重复项

IT技术 javascript arrays
2021-02-05 16:26:58

让我们假设我有;

var array = [1,2,3,4,4,5,5];

我希望它是;

var newArray = [1,2,3];

我想完全删除重复项,而不是将它们保留为唯一值。有没有办法通过 reduce 方法来实现?

6个回答

您可以使用Array#filterwithArray#indexOfArray#lastIndexOf并仅返回共享相同索引的值。

var array = [1, 2, 3, 4, 4, 5, 5],
    result = array.filter(function (v, _, a) {
        return a.indexOf(v) === a.lastIndexOf(v);
    });

console.log(result);

另一种方法是采用 aMap并将值设置为false,如果之前已经看到过一个键。然后通过获取地图的值来过滤数组。

var array = [1, 2, 3, 4, 4, 5, 5],
    result = array.filter(
        Map.prototype.get,
        array.reduce((m, v) => m.set(v, !m.has(v)), new Map)
    );

console.log(result);

这很漂亮。我也没有想到 lastIndexOf 。
2021-03-13 16:26:58
没想到lastIndexOf- 很好的解决方案!
2021-03-20 16:26:58
好的!第二个例子在算法顺序上更好;它在过滤器中非常巧妙地使用了 thisArg,我只是通过阅读答案来学习。谢谢!
2021-04-11 16:26:58

我想它不会有什么非凡的表现,但我喜欢这个主意。

var array = [1,2,3,4,4,5,5],
    res = array.reduce(function(s,a) {
      if (array.filter(v => v !== a).length == array.length-1) {
        s.push(a);
      }
      return s;
    }, []);
    console.log(res);

另一种选择是使用对象来跟踪元素被使用的次数。这将破坏数组顺序,但在非常大的数组上应该快得多。

function nukeDuplications(arr) {
  const hash = {};
  arr.forEach(el => {
    const qty = hash[el] || 0;
    hash[el] = qty+1;
  });
  
  const ret = [];
  Object.keys(hash).forEach(key => {
    if (hash[key] === 1) {
      ret.push(Number(key));
    }
  })
  return ret;
}

var array = [1,2,3,4,4,5,5];
console.log(nukeDuplications(array));

稍微更有效的解决方案是循环数组 1 次并计算每个值中出现的次数并将它们存储在对象中 using.reduce()然后再次循环数组.filter()只返回出现 1 次的项目。

此方法还将保留数组的顺序,因为它仅使用对象键作为引用 - 它不会迭代它们。

var array = [1,2,3,4,4,5,5];
var valueCounts = array.reduce((result, item) => {
    if (!result[item]) {
        result[item] = 0;
    }
    result[item]++;
    return result;
}, {});
 
var unique = array.filter(function (elem) {
    return !valueCounts[elem] || valueCounts[elem] <= 1;
}); 
 
console.log(unique)

另一种选择是使用对象来跟踪元素被使用的次数。这将破坏数组顺序,但在非常大的数组上应该快得多。

// Both versions destroy array order.

// ES6 version
function nukeDuplications(arr) {
  "use strict";
  const hash = {};
  arr.forEach(el => {
    const qty = hash[el] || 0;
    hash[el] = qty + 1;
  });

  const ret = [];
  Object.keys(hash).forEach(key => {
    if (hash[key] === 1) {
      ret.push(Number(key));
    }
  })
  return ret;
}

// ES5 version
function nukeDuplicationsEs5(arr) {
  "use strict";
  var hash = {};
  for (var i = 0; i < arr.length; i++) {
    var el = arr[i];
    var qty = hash[el] || 0;
    hash[el] = qty + 1;
  };

  var ret = [];
  for (let key in hash) {
    if (hash.hasOwnProperty(key)) {
        if (hash[key] === 1) {
          ret.push(Number(key));
        }
      }
    }
    return ret;
  }


  var array = [1, 2, 3, 4, 4, 5, 5];
  console.log(nukeDuplications(array));

  console.log(nukeDuplicationsEs5(array));