本文介绍一种源自YUI源码的高效JavaScript数组去重方法。核心思路是利用对象键(key)的唯一性,先将数组元素作为键存入对象以自动去重,再提取键名重组为数组。该方法仅需遍历数组和对象各一次,相比传统双重循环对比,性能显著提升。测试表明其适用于字符串和数字的一维数组。
定期研读YUI框架的源代码,往往能带来意想不到的技术启发。
YUI源码中的去重实现
一. YUI中的源码实现
具体代码实现如下:
var toObject = function(a) {
var o = {};
for (var i=0, j=a.length; i<j; i=i+1) { // 此处对原YUI源码进行了微调,原代码中判断条件为 i<a.length
o[a[i]] = true;
}
return o;
};
var keys = function(o) {
var a=[], i;
for (i in o) {
if (o.hasOwnProperty(i)) { // 注意:原YUI源码中此处调用的是 lang.hasOwnProperty(o, i)
a.push(i);
}
}
return a;
};
var uniq = function(a) {
return keys(toObject(a));
}; 注:为便于阅读,上述代码省略了YUI类名前缀。读者可自行查阅YUI 2.7.0b或2.8.0r4版本的源码,该部分代码在两个版本中保持一致。
核心思路解析
二. 该方法的核心思路
1. 首先,以目标数组的元素值为键(key),构建一个对象。这是最关键的一步:由于JavaScript对象的键具有唯一性,重复的元素在赋值给同一键时会被覆盖,从而巧妙地实现了去重;
2. 接着,遍历生成的对象,提取所有的键名并推入一个新数组。至此,去重操作完成(整个过程仅需两步,非常简洁)。
方法特点与适用场景
三. 该方法的特点分析
1. 无论数组包含多少项,该方法仅执行两次遍历(一次构建对象,一次提取键名)。相较于以往逐个对比数组元素的低效做法,其性能优势极为明显;
2. 经测试验证,该方法主要适用于元素类型为字符串或数字的一维数组(对于多维数组的去重操作,此方法并不适用,处理起来较为复杂)。
其他去重方法的参考可查阅前文。