我有一组数字,我需要确保它们是唯一的。我在互联网上找到了下面的代码片段,它工作得很好,直到数组中有一个零。我在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数组中删除重复值
类似的问题:
获取数组中的所有非唯一值(即:重复/多次出现)
这里的许多答案可能对初学者没有帮助。如果数组的重复数据消除很困难,他们真的会知道原型链,甚至jQuery吗?
在现代浏览器中,一个干净而简单的解决方案是将数据存储在一个集合中,该集合被设计为一个唯一值列表。
const cars=[“沃尔沃”、“吉普”、“沃尔沃”,“林肯”、“林肯”和“福特”];constuniqueCars=Array.from(新集合(cars));console.log(uniqueCars);
Array.from用于将Set转换回Array,以便您可以轻松访问数组所具有的所有很棒的方法(功能)。同样的事情还有其他方法。但您可能根本不需要Array.from,因为Sets有很多有用的功能,比如forEach。
如果您需要支持旧的Internet Explorer,因此无法使用Set,那么一种简单的方法是将项目复制到新阵列中,同时预先检查它们是否已在新阵列中。
// Create a list of cars, with duplicates.
var cars = ['Volvo', 'Jeep', 'Volvo', 'Lincoln', 'Lincoln', 'Ford'];
// Create a list of unique cars, to put a car in if we haven't already.
var uniqueCars = [];
// Go through each car, one at a time.
cars.forEach(function (car) {
// The code within the following block runs only if the
// current car does NOT exist in the uniqueCars list
// - a.k.a. prevent duplicates
if (uniqueCars.indexOf(car) === -1) {
// Since we now know we haven't seen this car before,
// copy it to the end of the uniqueCars list.
uniqueCars.push(car);
}
});
为了使其立即可重用,让我们将其放在函数中。
function deduplicate(data) {
if (data.length > 0) {
var result = [];
data.forEach(function (elem) {
if (result.indexOf(elem) === -1) {
result.push(elem);
}
});
return result;
}
}
所以为了消除重复,我们现在就这样做。
var uniqueCars = deduplicate(cars);
当函数完成时,重复数据消除(cars)部分将成为我们命名为result的部分。
只需将您喜欢的任何数组的名称传递给它即可。
很多人已经提到使用。。。
[...new Set(arr)];
这是一个很好的解决方案,但我的首选是与.filter一起使用的解决方案。在我看来,filter是获取唯一值的更自然的方法。您可以有效地删除重复项,而从数组中删除元素正是过滤器的作用所在。它还允许您链接.map、.reduce和其他.filter调用。我设计了这个解决方案。。。
const unique = () => {
let cache;
return (elem, index, array) => {
if (!cache) cache = new Set(array);
return cache.delete(elem);
};
};
myArray.filter(unique());
需要注意的是,你需要一个结束,但我认为这是一个值得的权衡。就性能而言,它比我看到的使用.filter的其他解决方案更具性能,但比[…new Set(arr)]性能更差。
另请参阅我的github包
这已经得到了很多回答,但并没有解决我的特殊需求。
许多答案是这样的:
a.filter((item, pos, self) => self.indexOf(item) === pos);
但这对复杂对象的数组不起作用。
假设我们有一个这样的数组:
const a = [
{ age: 4, name: 'fluffy' },
{ age: 5, name: 'spot' },
{ age: 2, name: 'fluffy' },
{ age: 3, name: 'toby' },
];
如果我们想要具有唯一名称的对象,我们应该使用array.prototype.findIndex而不是array.protoype.indexOf:
a.filter((item, pos, self) => self.findIndex(v => v.name === item.name) === pos);