tanya
tanya

Reputation: 2985

jQuery.unique() not returning completely distinct values

I am using the 'jQuery.unique()' function to put distinct array values from one array to another array but the values in the 2nd array does not seem to contain distinct values.

var nonuniqueArray = ['AMI:8244','AMI:29126','AMI:31591','AMI:31591','AMI:31591','AMI:31591','AMI:29126'];
uniqueArray = $j.unique(nonuniqueArray);
alert (uniqueArray);

Values alerted are: AMI:29126,AMI:31591,AMI:29126,AMI:8244

I noticed that if similar values in the array are grouped together, then it works fine, for e.g if 'AMI:29126' are grouped together, it seems ok.

Any suggestion on what's wrong with the above code is most welcomed.

Many many thanks :)

Upvotes: 2

Views: 3954

Answers (5)

Kamil Kiełczewski
Kamil Kiełczewski

Reputation: 92743

In ES6 you can do something like this:

Array.prototype.unique = function() {
    let newArray = [];
    for(let i=0, j=this.length; i<j; i++){
        if(newArray.indexOf(this[i]) == -1) newArray.push(this[i]);
    }
    this.splice(0, this.length, ...newArray);
}

And just run it by yourarray.unique() (it works inplace). If you dont yse ES6 you can replace this: this.splice(0, this.length, ...newArray); by these lines (I not test this code below):

this.splice(0, this.length)
for(el of newArray) { this.push(el) }

Upvotes: 0

Andy E
Andy E

Reputation: 344803

Here's a sample that's more efficient and compatible than Marlin's solution. indexOf is a somewhat expensive lookup on large arrays, so for strings it's much better to create a temporary object:

function strUnique(arr) {
    var obj = {},
        ret = [],
        i   = arr.length;

    while (i--) {
        if (!obj[arr[i]]) {
            obj[arr[i]] = true;
            ret.unshift(arr[i]);
        }
    }

    return ret;
}

If order is important, you may want to work forwards rather than backwards. If so you'll need to adjust the loop accordingly.

Upvotes: 0

Marlin
Marlin

Reputation: 749

here's how you could do this with regular Array methods, but i would note that indexOf() is a newer array method and won't work in IE7 or earlier but is easily duplicated with 1 loop

var nonuniqueArray = ['AMI:8244','AMI:29126','AMI:31591','AMI:31591','AMI:31591','AMI:31591','AMI:29126'];

function distinctVal(arr){
    var newArray = [];
    for(var i=0, j=arr.length; i<j; i++){
        if(newArray.indexOf(arr[i]) == -1)
              newArray.push(arr[i]);  
    }
    return newArray;
}

var uniqueArray = distinctVal(nonuniqueArray);
alert(uniqueArray);

Upvotes: 3

Niels
Niels

Reputation: 49959

The $.unique is not made for this see the following url: http://api.jquery.com/jQuery.unique/

The $.unique() function searches through an array of objects, sorting the array, and removing any duplicate nodes. This function only works on plain JavaScript arrays of DOM elements, and is chiefly used internally by jQuery.

What you can do is sort it first and then use unique, this is not exactly where it was made of, but it works.

var nonuniqueArray = ['AMI:8244','AMI:29126','AMI:31591','AMI:31591','AMI:31591','AMI:31591','AMI:29126'];
var sortedArray = Array.sort(nonuniqueArray );
var unique = $.unique(sortedArray);

$.each(unique , function(k, v){
    $("div").append(v + "<br />");
});

Result:

AMI:8244
AMI:31591
AMI:29126

LIVE DEMO: http://jsfiddle.net/9x4dR/

Upvotes: 4

James Allardice
James Allardice

Reputation: 166071

You can't use the jQuery unique method for arrays of Strings. It will only work on arrays of DOM elements. From the docs:

Sorts an array of DOM elements, in place, with the duplicates removed. Note that this only works on arrays of DOM elements, not strings or numbers.

Upvotes: 1

Related Questions