我有一组数字,我需要确保它们是唯一的。我在互联网上找到了下面的代码片段,它工作得很好,直到数组中有一个零。我在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数组中删除重复值
类似的问题:
获取数组中的所有非唯一值(即:重复/多次出现)
使用JavaScript 1.6/ECMAScript 5,您可以通过以下方式使用Array的本机筛选器方法来获得具有唯一值的数组:
仅函数唯一(值、索引、自身){return self.indexOf(value)==索引;}//用法示例:var a=['a',1,'a',2,'1'];var unique=a.filter(仅唯一);console.log(唯一);//[阿',1,2,'1']
本机方法筛选器将循环遍历数组,并只保留那些传递给定回调函数的条目。
如果给定值是第一个出现,则仅唯一检查。如果没有,它必须是副本,并且不会被复制。
这个解决方案不需要任何额外的库,如jQuery或prototype.js。
它也适用于具有混合值类型的数组。
对于不支持本机方法filter和indexOf的旧浏览器(<ie9),您可以在MDN文档中找到filter和indexOf的解决方法。
如果要保留值的最后一次出现,只需将indexOf替换为lastIndexOf。
使用ES6,这可以缩短为:
//用法示例:var myArray=['a',1,'a',2,'1'];var unique=myArray.filter((v,i,a)=>a.indexOf(v)==i);console.log(唯一);//唯一的是['a',1,2,'1']
感谢卡米洛·马丁的评论提示。
ES6有一个本地对象Set来存储唯一值。要获得具有唯一值的数组,现在可以执行以下操作:
var myArray=['a',1,'a',2,'1'];let unique=[…new Set(myArray)];console.log(唯一);//唯一的是['a',1,2,'1']
Set的构造函数接受一个可迭代的对象,如Array,而扩展运算符。。。将集合转换回数组。感谢Lukas Liese的评论提示。
最简单的方法是将值转换为字符串,以过滤嵌套的对象值。
const uniq = (arg = []) => {
const stringifyedArg = arg.map(value => JSON.stringify(value))
return arg.filter((value, index, self) => {
if (typeof value === 'object')
return stringifyedArg.indexOf(JSON.stringify(value)) === index
return self.indexOf(value) === index
})
}
console.log(uniq([21, 'twenty one', 21])) // [21, 'twenty one']
console.log(uniq([{ a: 21 }, { a: 'twenty one' }, { a: 21 }])) // [{a: 21}, {a: 'twenty one'}]
使用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()];
["Defects", "Total", "Days", "City", "Defects"].reduce(function(prev, cur) {
return (prev.indexOf(cur) < 0) ? prev.concat([cur]) : prev;
}, []);
[0,1,2,0,3,2,1,5].reduce(function(prev, cur) {
return (prev.indexOf(cur) < 0) ? prev.concat([cur]) : prev;
}, []);