我有一组数字,我需要确保它们是唯一的。我在互联网上找到了下面的代码片段,它工作得很好,直到数组中有一个零。我在Stack Overflow上找到了另一个脚本,看起来几乎与它完全一样,但它不会失败。

所以为了帮助我学习,有人能帮我确定原型脚本哪里出错吗?

Array.prototype.getUnique = function() {
 var o = {}, a = [], i, e;
 for (i = 0; e = this[i]; i++) {o[e] = 1};
 for (e in o) {a.push (e)};
 return a;
}

重复问题的更多答案:

从JS数组中删除重复值

类似的问题:

获取数组中的所有非唯一值(即:重复/多次出现)


当前回答

使用ES6(一个衬垫)

基元值数组

let originalArr= ['a', 1, 'a', 2, '1'];

let uniqueArr = [...new Set(originalArr)];

对象阵列

let uniqueObjArr = [...new Map(originalObjArr.map((item) => [item["propertyName"], item])).values()];

const ObjArray = [
    {
        name: "Eva Devore",
        character: "Evandra",
        episodes: 15,
    },
    {
        name: "Alessia Medina",
        character: "Nixie",
        episodes: 15,
    },
    {
        name: "Kendall Drury",
        character: "DM",
        episodes: 15,
    },
    {
        name: "Thomas Taufan",
        character: "Antrius",
        episodes: 14,
    },
    {
        name: "Alessia Medina",
        character: "Nixie",
        episodes: 15,
    },
];

let uniqueObjArray = [...new Map(ObjArray.map((item) => [item["id"], item])).values()];

其他回答

您也可以使用underscore.js。

控制台日志(_.uniq([1,2,1,3,1,4]));<script src=“http://underscorejs.org/underscore-min.js“></script>

其将返回:

[1, 2, 3, 4]

如果有人使用knockoutjs

ko.utils.arrayGetDistinctValues()

顺便说一下,我们已经了解了所有ko.utils.array*实用程序。

我有一个简单的例子,我们可以从数组中删除对象,

  let data = new Array({id: 1},{id: 2},{id: 3},{id: 1},{id: 3});
  let unique = [];
  let tempArr = [];
  console.log('before', data);
  data.forEach((value, index) => {
    if (unique.indexOf(value.id) === -1) {
      unique.push(value.id);
    } else {
      tempArr.push(index);    
    }
  });
  tempArr.reverse();
  tempArr.forEach(ele => {
    data.splice(ele, 1);
  });
  console.log(data);

对于一个元组数组,我将把它们放到一个Map中,让它完成工作。使用此方法时,您必须注意要使用的密钥:

const arrayOfArraysWithDuplicates = [
    [1, 'AB'],
    [2, 'CD'],
    [3, 'EF'],
    [1, 'AB'],
    [2, 'CD'],
    [3, 'EF'],
    [3, 'GH'],
]

const uniqueByFirstValue = new Map();
const uniqueBySecondValue = new Map();

arrayOfArraysWithDuplicates.forEach((item) => {
    uniqueByFirstValue.set(item[0], item[1]);
    uniqueBySecondValue.set(item[1], item[0]);
});

let uniqueList = Array.from( uniqueByFirstValue, ( [ value, name ] ) => ( [value, name] ) );

console.log('Unique by first value:');
console.log(uniqueList);

uniqueList = Array.from( uniqueBySecondValue, ( [ value, name ] ) => ( [value, name] ) );

console.log('Unique by second value:');
console.log(uniqueList);

输出:

Unique by first value:
[ [ 1, 'AB' ], [ 2, 'CD' ], [ 3, 'GH' ] ]

Unique by second value:
[ [ 'AB', 1 ], [ 'CD', 2 ], [ 'EF', 3 ], [ 'GH', 3 ] ]

这里有一个几乎是一行的O(n),保留了第一个元素,并且在这里你可以将你正在uniq'ing上的字段分开。

这是函数式编程中非常常见的技术——您可以使用reduce来构建返回的数组。因为我们这样构建数组,所以我们保证得到稳定的排序,这与[…new Set(array)]方法不同。我们仍然使用Set来确保没有重复,因此我们的累加器同时包含Set和我们正在构建的数组。

常量删除重复项=(arr)=>减少(([set,acc],item)=>集合有(item)?[set,acc]:[set.add(项目),(acc.push(项目)、acc)],[新设置(),[]])[1]

上述方法适用于简单值,但不适用于对象,类似于[…new Set(array)]的分解方式。如果项目是包含id属性的对象,您应该执行以下操作:

常量删除重复项=(arr)=>减少(([set,acc],item)=>集合有(item.id)?[set,acc]:[set.add(item.id),(acc.push(item),acc)],[新设置(),[]])[1]