如何删除一个数组中的重复元素?

先来看看淘宝UED官方博客的一个题目:(http://ued.taobao.org/blog/2007/11/job_test_explanation/)
请给Array本地对象增加一个原型方法,
它的用途是删除数组条目中重复的条目(可能有多个),
返回值是一个包含被删除的重复条目的新数组。

Array.prototype.distinct = function() {
var ret = [];
for (var i = 0; i < this.length; i++) {
for (var j = i+1; j < this.length;) {
if (this[i] === this[j]) {
ret.push(this.splice(j, 1)[0]);
} else {
j++;
}
}
}
return ret;
}
//for test
console.log(['a','b','c','a','d','b','a','e'].distinct()); //['a','a','b'] 正确

上面是淘宝官方给出的答案,下面是我给的答案。

Array.prototype.distinct = function() {
var ret = [];
for (var i = 0; i < this.length; i++) {
for (var j = i+1; j < this.length; j++) {
if (this[i] === this[j]) {
ret.push(this.splice(j, 1)[0]);
//注意:this.splice(j,1)返回的是一个数组,这个数组只有一个元素
}
}
}
}
//for test
console.log(['a','b','c','a','d','b','a','e'].distinct()); //['a','a','b'] 正确

咱一看,两者都一样,区别就在j++上,请仔细观察。
这两种写法所实现的功能都一样,下面更为自然,上面感觉就是牛。
我开始就是弄不明白官方为何要自己手动控制j++,表面上看好像效率更高。
但实际测试不然,我们在外面定义一个变量number,记录循环执行的次数。

Array.prototype.distinct = function() {
var ret = [];
var number = 0 ;
for (var i = 0; i < this.length; i++) {
for (var j = i+1; j < this.length;) {
if (this[i] === this[j]) {
ret.push(this.splice(j, 1)[0]);
//注意:this.splice(j,1)返回的是一个数组,这个数组只有一个元素
} else {
j++;
}
++number;
console.log(this + ','+number);
}
}
return ret + ','+number;
}
//for test
console.log(['a','b','c','a','d','b','a','e'].distinct()); //['a','a','b'] 正确
a,b,c,a,d,b,a,e,1
a,b,c,a,d,b,a,e,2
a,b,c,d,b,a,e,3
a,b,c,d,b,a,e,4
a,b,c,d,b,a,e,5
a,b,c,d,b,e,6
a,b,c,d,b,e,7
a,b,c,d,b,e,8
a,b,c,d,b,e,9
a,b,c,d,e,10
a,b,c,d,e,11
a,b,c,d,e,12
a,b,c,d,e,13
a,b,c,d,e,14
a,a,b,14

number为14,也就是循环了14次。
8个数循环14次,也很容易理解,就是7+4+2+1。
同理,测试我的写法:

Array.prototype.distinct = function() {
var ret = [];
var number = 0 ;
for (var i = 0; i < this.length; i++) {
for (var j = i+1; j < this.length; j++) {
if (this[i] === this[j]) {
ret.push(this.splice(j, 1)[0]);
//注意:this.splice(j,1)返回的是一个数组,这个数组只有一个元素
}
++number;
console.log(this + ','+number);
}
}
return ret + ','+number;
}
//for test
console.log(['a','b','c','a','d','b','a','e'].distinct()); //['a','a','b'] 正确
a,b,c,a,d,b,a,e,1
a,b,c,a,d,b,a,e,2
a,b,c,d,b,a,e,3
a,b,c,d,b,a,e,4
a,b,c,d,b,e,5
a,b,c,d,b,e,6
a,b,c,d,b,e,7
a,b,c,d,e,8
a,b,c,d,e,9
a,b,c,d,e,10
a,b,c,d,e,11
a,a,b,11

number为11,循环了11次。
8个数循环11次,按运算逻辑理解,就是7+2+1+1。
少了3次,感觉很奇怪吧。
我也是觉得不可思议,从代码来看,明显上面执行效率更高,但实际下面的执行效率更高。
它智能地跳过了几次比较,所以效率更高。
为何会智能跳过呢?我只能理解成CPU更聪明。
期待大牛来帮我解答,感激不尽!