我有一组数字,我需要确保它们是唯一的。我在互联网上找到了下面的代码片段,它工作得很好,直到数组中有一个零。我在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提供uniq方法:https://api.jquery.com/jQuery.unique/
var ids_array = []
$.each($(my_elements), function(index, el) {
var id = $(this).attr("id")
ids_array.push(id)
});
var clean_ids_array = jQuery.unique(ids_array)
$.each(clean_ids_array, function(index, id) {
elment = $("#" + id) // my uniq element
// TODO WITH MY ELEMENT
});
我将所有答案分成4种可能的解决方案:
使用对象{}防止重复使用助手数组[]使用筛选器+indexOf奖金ES6设置方法。
以下是答案中的示例代码:
使用对象{}防止重复
function uniqueArray1( ar ) {
var j = {};
ar.forEach( function(v) {
j[v+ '::' + typeof v] = v;
});
return Object.keys(j).map(function(v){
return j[v];
});
}
使用助手数组[]
function uniqueArray2(arr) {
var a = [];
for (var i=0, l=arr.length; i<l; i++)
if (a.indexOf(arr[i]) === -1 && arr[i] !== '')
a.push(arr[i]);
return a;
}
使用筛选器+indexOf
function uniqueArray3(a) {
function onlyUnique(value, index, self) {
return self.indexOf(value) === index;
}
// usage
var unique = a.filter( onlyUnique ); // returns ['a', 1, 2, '1']
return unique;
}
使用ES6[…新集合(a)]
function uniqueArray4(a) {
return [...new Set(a)];
}
我想知道哪一个更快。我已经制作了测试功能的GoogleSheet样本。注意:ECMA 6在Google Sheets中不可用,所以我无法测试它。
以下是测试结果:
我希望看到使用对象{}的代码将获胜,因为它使用哈希。因此,我很高兴测试在Chrome和IE中显示了该算法的最佳结果。感谢@rab的代码。
2020年更新
启用谷歌脚本的ES6引擎。现在我用Sets测试了最后一段代码,它看起来比对象方法更快。
使用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()];
最简单的方法是将值转换为字符串,以过滤嵌套的对象值。
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函数,它从对象数组中删除重复项,并按指定的对象属性进行筛选
function dedupe(arr = [], fnCheck = _ => _) {
const set = new Set();
let len = arr.length;
for (let i = 0; i < len; i++) {
const primitive = fnCheck(arr[i]);
if (set.has(primitive)) {
// duplicate, cut it
arr.splice(i, 1);
i--;
len--;
} else {
// new item, add it
set.add(primitive);
}
}
return arr;
}
const test = [
{video:{slug: "a"}},
{video:{slug: "a"}},
{video:{slug: "b"}},
{video:{slug: "c"}},
{video:{slug: "c"}}
]
console.log(dedupe(test, x => x.video.slug));
// [{video:{slug: "a"}}, {video:{slug: "b"}}, {video:{slug: "c"}}]