DrStrangeLove DrStrangeLove - 6 months ago 19
Javascript Question

How do I make an array with unique elements (i.e. remove duplicates)?

I have this code:

var ar = [10,7,8,3,4,7,6];

function isin(n,a){
for (var i=0;i<a.length;i++){
if (a[i]== n) {
var b = true;
return b;
} else {
var c = false;
return c;
}
}
}

function unique(a){
var arr = [];
for (var i=0;i<a.length;i++){
if (!isin(a[i],arr)){
arr.push(a[i]);
}
}

return arr;
}

alert(unique(ar));


In this code, I try to create new unique array (without duplicates) out of the original one.
But I still get the original array! Where's my mistake?

Answer

Using a plain array and returning the keys of associative array (containing only the "unique" values from given array) is more efficient:

function ArrNoDupe(a) {
    var temp = {};
    for (var i = 0; i < a.length; i++)
        temp[a[i]] = true;
    var r = [];
    for (var k in temp)
        r.push(k);
    return r;
}

$(document).ready(function() {
    var arr = [10, 7, 8, 3, 4, 3, 7, 6];
    var noDupes = ArrNoDupe(arr);
    $("#before").html("Before: " + arr.join(", "));
    $("#after").html("After: " + noDupes.join(", "));
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="before"></div>
<div id="after"></div>

Note: The function does not preserve the order of the items, so if this is important use different logic.

As of IE9 and on all other modern browsers (e.g. Chrome, Firefox) this can become even more efficient by using the Object.keys() method:

function ArrNoDupe(a) {
    var temp = {};
    for (var i = 0; i < a.length; i++)
        temp[a[i]] = true;
    return Object.keys(temp);
}

$(document).ready(function() {
    var arr = [10, 7, 8, 3, 4, 3, 7, 6];
    var noDupes = ArrNoDupe(arr);
    $("#before").html("Before: " + arr.join(", "));
    $("#after").html("After: " + noDupes.join(", "));
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="before"></div>
<div id="after"></div>

Thanks wateriswet for bringing this to my attention. :)