Code that can be used directly: Script House revised version
]
The following is an advanced tutorial and Note, friends who like to follow it in depth can refer to it.
First let us see how YUI handles it:
The code is as follows:
var toObject = function(a) {
var o = {};
for (var i = 0; i < a.length; i = i 1) {
o[a[i ]] = true;
}
return o;
};
var keys = function(o) {
var a=[], i;
for ( i in o) {
if (lang.hasOwnProperty(o, i)) { // YUI method
a.push(i);
}
}
return a;
};
var uniq = function(a) {
return keys(toObject(a));
};
For detailed analysis, see your colleague Tian's sharing "Cleverly Removing Duplicates from Arrays".
The method I use is very similar to YUI's method, but only one loop is used to delete duplicate items in the array, as follows:
The code is as follows:
var uniq = function (arr) {
var a = [],
o = {},
i,
v,
len = arr.length;
if (len < 2) {
return arr;
}
for (i = 0; i < len; i ) {
v = arr[i];
if (o[v] !== 1) {
a.push(v);
o[ v] = 1;
}
}
return a;
}
After a simple test: the performance of the method I used is much higher than YUI way.
We welcome everyone to provide better solutions.
Updated on December 28, 2009:
The above two function methods cannot handle complex arrays containing mixed types for the time being (thanks to Mao Mao for raising the question), such as: [0, "0",1,"1",0], ["null",null].
For arrays whose types can be agreed to be numbers (note: numbers starting with non-0, except decimals) or strings, we can use the improved function method (thanks to closurecache for the idea):
The code is as follows:
var uniq = function (arr) {
var a = [ ],
o = {},
i,
v,
cv, // corrected value
len = arr.length;
if (len < 2 ) {
return arr;
}
for (i = 0; i < len; i ) {
v = arr[i];
/* The function provided by closurecache uses cv = v 0;,
* so that arrays like [1, 10, "1", "10"] cannot be distinguished,
* because after operation => 1 , 10, 10, 100. Obviously, there are duplicate identifiers. Is it okay to add
* in front of it?
* Yes: Numbers like 01 and 001, starting with 0, cannot appear in the array,
* but its applicability is wider than before.
*/
cv = 0 v;
if (!o[cv]) {
a.push(v);
o[cv] = true;
}
}
return a;
}
If you want to make it more perfect based on this problem-solving idea, I recommend Dexter.Yy’s method , perform type judgment and give a unique identifier. See comments on the 20th floor for details.
There is no best, only the most appropriate way. In fact, the idea of using Array.indexOf() is also a good choice. For browsers that already support it, use the native Array.indexOf() method directly. For browsers that do not support it, use the native Array.indexOf() method directly. Yes, we add the Array.indexOf() method as follows:
The code is as follows:
if(!Array.prototype.indexOf) {
Array.prototype.indexOf = function (obj, fromIndex) {
if (fromIndex == null) {
fromIndex = 0;
} else if (fromIndex < 0) {
fromIndex = Math.max(0, this.length fromIndex);
}
for (var i = fromIndex; i < this.length; i ) {
if (this[i] === obj)
return i;
}
return -1;
};
}
Next, the implementation process is very simple.
<script>
function unique(data){
data = data || [];
var a = {};
len = data.length;
for (var i=0; i<len;i++){
var v = data[i];
if (typeof(a[v]) == 'undefined'){
a[v] = 1;
}
};
data.length=0;
for (var i in a){
data[data.length] = i;
}
return data;
}
function test(){
var arr = [9,1,3,8,7,7,6,6,5,7,8,8,7,4,3,1];
var arr1 = unique(arr);
alert(arr1.join(","));
}
test();
</script>Optimization tips for implementing solutions using the Array.indexOf() method: When the same value is found, remove it from the array to reduce the amount of the next traversal.