Rumah > Soal Jawab > teks badan
一般来说是建立一个哈希表,类似这样
var arr = [1, 2, 2, 3, 4, 5, 6, 6];
function getArray(a) {
var hash = {},
len = a.length,
result = [];
for (var i = 0; i < len; i++){
if (!hash[a[i]]){
hash[a[i]] = true;
result.push(a[i]);
}
}
return result;
}
getArray(arr); // 输出[1, 2, 3, 4, 5, 6]
里面有对对象属性的查询,这个性能肯定不是最好的,所以问对js来说是否还有更加高效?
迷茫2017-04-10 12:47:32
测试环境是Linux Sandybridge i5 x86-64下的chrome 26(下称v8)和firefox 20(下称ionmonkey)
// 纯数字
var mkArr = function(len, dev) {
var xs = new Array(len);
for (var i = 0; i < len; ++i) {
xs[i] = Math.floor(Math.random() * dev);
}
return xs;
};
// 字符串和数字混在一起
var mkMixedArr = function(len, dev) {
var xs = new Array(len);
for (var i = 0; i < len; ++i) {
var t = Math.floor(Math.random() * dev);
xs[i] = Math.random() > 0.5 ? t : String(t);
}
return xs;
};
// 纯object
var mkObjArr = function(len, dev) {
var allObjs = new Array(dev);
for (var i = 0; i < dev; ++i) {
allObjs[i] = {x: /* For debugging */ i};
}
var xs = new Array(len);
for (var i = 0; i < len; ++i) {
xs[i] = allObjs[Math.floor(Math.random() * dev)];
}
return xs;
};
v8/mkArr(3000, 3000)
v8/mkMixedArr(3000, 3000)
v8/mkObjArr(10000, 10000)
ionmonkey/mkArr(3000, 3000)
ionmonkey/mkMixedArr(3000, 3000)
ionmonkey/mkObjArr(10000, 10000)
黄舟2017-04-10 12:47:32
underscorejs的效率好低,将之前的元素push入一个新数组,然后再每次判断元素是否已存在这个数组内。
underscorejs的代码如下:
_.uniq = _.unique = function(array, isSorted, iterator, context) {
if (_.isFunction(isSorted)) {
context = iterator;
iterator = isSorted;
isSorted = false;
}
var initial = iterator ? _.map(array, iterator, context) : array;
var results = [];
var seen = [];
each(initial, function(value, index) {
if (isSorted ? (!index || seen[seen.length - 1] !== value) : !_.contains(seen, value)) {
seen.push(value);
results.push(array[index]);
}
});
return results;
};
jQuery的方法是先排序,然后从第二个元素开始只循环一次,每次和上一元素比较。 并且只记录需要删除的下标,然后删除原数组中的重复项,这样避免了元素太大而导致的效率问题,应该是最高效的了
jQuery的代码如下
Sizzle.uniqueSort = function(results) {
var elem,
duplicates = [],
i = 1,
j = 0;
// Unless we *know* we can detect duplicates, assume their presence
hasDuplicate = !support.detectDuplicates;
results.sort(sortOrder);
if (hasDuplicate) {
for (;
(elem = results[i]); i++) {
if (elem === results[i - 1]) {
j = duplicates.push(i);
}
}
while (j--) {
results.splice(duplicates[j], 1);
}
}
return results;
};