我有一组数字,我需要确保它们是唯一的。我在互联网上找到了下面的代码片段,它工作得很好,直到数组中有一个零。我在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数组中删除重复值
类似的问题:
获取数组中的所有非唯一值(即:重复/多次出现)
下面是另一种使用比较器的方法(我更关心干净的代码而不是性能):
const list = [
{name: "Meier"},
{name: "Hans"},
{name: "Meier"},
]
const compare = (a, b) => a.name.localeCompare(b.name);
const uniqueNames = list.makeUnique(compare);
uniqueNames.pushIfAbsent({name: "Hans"}, compare);
原型声明:
declare global {
interface Array<T> {
pushIfAbsent(item: T, compare:(a:T, b:T)=>number): number;
}
interface Array<T> {
makeUnique(compare:(a:T, b:T)=>number): Array<T>;
}
}
Array.prototype.pushIfAbsent = function <T>(this:T[], item:T, compare:(a:T, b:T)=>number) {
if (!this.find(existing => compare(existing, item)===0)) {
return this.push(item)
} else {
return this.length;
}
}
Array.prototype.makeUnique = function <T>(this:T[], compare:(a:T, b:T)=>number) {
return this.filter((existing, index, self) => self.findIndex(item => compare(existing, item) == 0) == index);
}
使用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的评论提示。
我有一个简单的例子,我们可以从数组中删除对象,
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);
ES2016.includes()一种方法简单答案:
var arr = [1,5,2,4,1,6]
function getOrigs(arr) {
let unique = []
arr && arr.forEach(number => {
!unique.includes(number) && unique.push(number)
if (number === arr[arr.length - 1]) {
console.log('unique: ', unique)
}
})
}
getOrigs(arr)
请改用此选项:
更新的ES版本简单问题不应使用多个高级JS方法,push()、length()和forEach()是常见的使用闭包更容易阅读在内存、垃圾收集和性能方面似乎比其他产品更好更少的代码行:如果您根据行结尾的位置分隔行,则只需要一行逻辑(因此您可以根据需要调用或重构这一行):
var arr = [1,5,2,4,1,6];
function getOrigs(arr) {let unique = [];
arr && arr.forEach(number => !unique.includes(number) && unique.push(number) && ((number === arr[arr.length - 1]) && console.log('unique: ', unique)))};
getOrigs(arr);
我想从对象数组中删除重复项。重复项具有相同的ID。这是我所做的。
// prev data
const prev = [
{
id: 1,
name: "foo",
},
{
id: 2,
name: "baz",
},
{
id: 1,
name: "foo",
},
];
// method:
// Step 1: put them in an object with the id as the key. Value of same id would get overriden.
// Step 2: get all the values.
const tempObj = {};
prev.forEach((n) => (tempObj[n.id] = n));
const next = Object.values(tempObj);
// result
[
{
id: 1,
name: "foo",
},
{
id: 2,
name: "baz",
}
];