Use PHP functions in JavaScript

JavaScript array_unique

Removes duplicate values from array

1
2
3
4
56
7
8
9
1011
12
13
14
1516
17
18
19
2021
22
23
24
2526
27
28
29
3031
32
33
34
3536
37
38
39
4041
42
43
44
function array_unique (inputArr) {
    // Removes duplicate values from array  
    // 
    // version: 1002.420
    // discuss at: http://phpjs.org/functions/array_unique    // +   original by: Carlos R. L. Rodrigues (http://www.jsfromhell.com)
    // +      input by: duncan
    // +   bugfixed by: Kevin van Zonneveld (http://kevin.vanzonneveld.net)
    // +   bugfixed by: Nate
    // +      input by: Brett Zamir (http://brett-zamir.me)    // +   bugfixed by: Kevin van Zonneveld (http://kevin.vanzonneveld.net)
    // +   improved by: Michael Grier
    // +   bugfixed by: Brett Zamir (http://brett-zamir.me)
    // %          note 1: The second argument, sort_flags is not implemented;
    // %          note 1: also should be sorted (asort?) first according to docs    // *     example 1: array_unique(['Kevin','Kevin','van','Zonneveld','Kevin']);
    // *     returns 1: {0: 'Kevin', 2: 'van', 3: 'Zonneveld'}
    // *     example 2: array_unique({'a': 'green', 0: 'red', 'b': 'green', 1: 'blue', 2: 'red'});
    // *     returns 2: {a: 'green', 0: 'red', 1: 'blue'}
    var key = '', tmp_arr2 = {}, val = ''; 
    var __array_search = function (needle, haystack) {
        var fkey = '';
        for (fkey in haystack) {
            if (haystack.hasOwnProperty) {                if ((haystack[fkey] + '') === (needle + '')) {
                    return fkey;
                }
            }
        }        return false;
    };
 
    for (key in inputArr) {
        if (inputArr.hasOwnProperty) {            val = inputArr[key];
            if (false === __array_search(val, tmp_arr2)) {
                tmp_arr2[key] = val;
            }
        }    }
 
    return tmp_arr2;
}
external links: original PHP docs | raw js source

Examples

» Example 1

Running

1
array_unique(['Kevin','Kevin','van','Zonneveld','Kevin']);

Should return

1
{0: 'Kevin', 2: 'van', 3: 'Zonneveld'}

» Example 2

Running

1
array_unique({'a': 'green', 0: 'red', 'b': 'green', 1: 'blue', 2: 'red'});

Should return

1
{a: 'green', 0: 'red', 1: 'blue'}

Dependencies

No dependencies, you can use this function standalone.

Open syntax issues

php.js uses JsLint to help us keep our code consistent and prevent some common bugs.

Eventually we want all code to pass or at least take into consideration most fixes suggested by JsLint, following this JsLint configuration we’ve decided on.


Authors

Thanks to the following developers, you get to have array_unique goodness in JavaScript.

Comments

Add Comment
Use:
[CODE]
your_stuff('here');
[/CODE]
for proper code formatting
By submitting code here you are allowing us to use it in php.js hence dual licensing it under the MIT and GPL licenses

Gravatar
Brett Zamir
Feb 4th Permalink

q  @nitin gupta: Thanks--I've fixed it in Git. I think it is a relic of the fact that we noticed that we may still _need_ to sort according to the docs, but I'm a bit busy to look at fixing this now myself.

Gravatar
nitin gupta
Feb 2nd Permalink

q  Hi Kevin,

I do not see this function being dependent on asort, may be a little documentation error.

Regards,

Gravatar
Kevin van Zonneveld
14 Apr '09 Permalink

q  Great work guys, I'll deploy shortly

Gravatar
Brett Zamir
14 Apr '09 Permalink

q  Ok, I made the strict fix, Michael, in SVN, thank you!

However, I'm not sure about the array-to-objects issue. Although we can get an array to return, due to the nature of JS, it will only contain the numerically indexed items within the array (and the length will be the total of those only). The other items would be added as properties of that array's object, and not be counted with length, though they are iteratable. Kevin has chosen to implement PHP arrays as regular (non-array) objects, so that we can support associative arrays. Granted we could theoretically return arrays with object properties, but that might be more confusing, and perhaps is the reason he chose not to do that.

One solution, might be to detect whether the input array was indeed a genuine array (which could only be numerically indexed), and if so, build a bona fide array as output too, but the problem with that is that the PHP behavior is to preserve keys, and we cannot preserve keys unless we build an object (or delete/cause to be undefined, those items which are no longer in use, but that still keeps the array length)--the one rare exception where we could safely return a regular array would be if all of the unique items were at the front of the array... So, not any good answers, I suspect, though I imagine you personally should be able to adapt the output of our function to the form you need for Greasemonkey... Best wishes, Brett

Gravatar
Michael Grier
13 Apr '09 Permalink

q   I found out if you're using this in GreaseMonkey, objects won't return. I changed the tmp_arr declarations to array, and it started working for me.

Also, regarding the strict var, PHP always does a strict comparison after casting the arguments to strings. So you could do the following:

1
2
3
if ((haystack[fkey] + "") === (needle + "")) {
    return fkey;
}

Gravatar
Kevin van Zonneveld
9 Nov '08 Permalink

q  @ Nate: Thank you for noticing!

Gravatar
Nate
6 Nov '08 Permalink

q   It looks like someone forgot to declare "val" with var.

I think the first line of code should read:

1
var key = '', tmp_arr1 = {}, tmp_arr2 = {}, val;


Otherwise, "val" is a global variable, I believe.

Is there any benefit to using var in a for loop? Would it be better to also declare "fkey" with "strict"?

Also, I don't know if this is important, but there is no space between "for" and "if" and the opening parentheses in __array_search().

Gravatar
Kevin van Zonneveld
27 Aug '08 Permalink

q  @ Nosredna: That's an idea that calls for a function rewrite. Interested? ;)

Gravatar
Nosredna
5 Aug '08 Permalink

q  Stray thought. The nested loops make me wonder how slow this is for large arrays.

Perhaps you could clone the array, sort the clone, then walk the two arrays deleting the dupes as you go. Sort is probably O(n log n) and maybe it's especially fast when no user sort evaluation routine is passed in.

Gravatar
Kevin van Zonneveld
25 Jul '08 Permalink

q   @ sankai: Thank you so much! But this array_unique does not support associative arrays (javascript objects). So unlike PHP's implementation, arrays that have non-numeric keys do not work.

Sad to say that my implementation didn't support it either, but I'm looking to replace array_unique with one that does support:

1
{firstname: 'Kevin', surname: 'van Zonneveld'}

.. style arrays

Gravatar
sankai
25 Jul '08 Permalink

q   the code I posted yesterday had big bug!I fixed it as the following:

1
2
3
4
56
7
8
9
1011
12
13
14
1516
17
18
19
2021
22
23
function array_unique(array,numeric){
    // http://blog.doublekai.org/
    // +   original by: sankai (http://blog.doublekai.org/)
    // *     example 1: array_unique([1,2,3,'1','2','3',1,2,3],true);
    // *     returns 1: [1,2,3]    // *     example 2: array_unique([1,2,3,'1','2','3',1,2,3]);
    // *     returns 2: [1,2,3,'1','2','3']
    // *     example 3: array_unique([1,'a','a','1','3',3,'b','c','b',1]);
    // *     returns 3: [1,'a','1','3',3,'b','c']
    // *     example 3: array_unique([1,'a','a','1','3',3,'b','c','b',1],true);    // *     returns 3: [1,'a',3,'b','c']    
    // *     NOTE :require function in_array()    
    var tem_arr = new Array();
    for(i=0;i<array.length;i++){
        if(numeric === true && typeof(array[i]) == 'string' && !isNaN(array[i])){             array[i]=parseInt(array[i],10);
        }
        if(!in_array(array[i],tem_arr)){
                tem_arr[i]=array[i];
        }    }
    return tem_arr.join(' ').replace(/\s{2,}/g,' ').split(' ');
}

The version need require function in_array

1
2
3
4
56
7
8
9
1011
12
13
14
1516
17
18
19
2021
22
23
24
2526
27
28
29
3031
32
33
34
35
function array_unique(array,numeric){
    // http://blog.doublekai.org/
    // +   original by: sankai (http://blog.doublekai.org/)
    // *     example 1: array_unique([1,2,3,'1','2','3',1,2,3],true);
    // *     returns 1: [1,2,3]    // *     example 2: array_unique([1,2,3,'1','2','3',1,2,3]);
    // *     returns 2: [1,2,3,'1','2','3']
    // *     example 3: array_unique([1,'a','a','1','3',3,'b','c','b',1]);
    // *     returns 3: [1,'a','1','3',3,'b','c']
    // *     example 3: array_unique([1,'a','a','1','3',3,'b','c','b',1],true);    // *     returns 3: [1,'a',3,'b','c']    
    // *     DON'T NEED require function in_array()    
    var tem_arr = new Array();
    for(i=0;i<array.length;i++){
        if(numeric === true && typeof(array[i]) == 'string' && !isNaN(array[i])){             array[i]=parseInt(array[i],10);
        }    
        if(tem_arr.length == 0){
            tem_arr[i] = array[i];
        } else {            var exist = false;
            for(var j=0; j<tem_arr.length; j++){
                if(tem_arr[j] === array[i]){
                    exist = true;
                }            }
            if(!exist){
                if(array[i] != null){
                    tem_arr[i] = array[i];
                }                }
        }
    }
    return tem_arr.join(' ').replace(/\s{2,}/g,' ').split(' ');
}

The version don't need require funciton in_array()

Gravatar
sankai
24 Jul '08 Permalink

q   Hi,I try to write a code for array_unique() as the following:

1
2
3
4
56
7
8
9
function array_unique(array){
    var tem_arr = new Array();
    for(i=0;i<array.length;i++){
        if(!in_array(array[i],tem_arr)){
            tem_arr[i]=array[i];        }
    }
    return tem_arr.join(',').split(',');
}

NOTE:It's require function in_array()

Gravatar
sankai
24 Jul '08 Permalink

q   Running:

1
array_unique(['Kevin','Kevin','van','Kevin']);

Return:
1
['Kevin','van','Kevin']

It's the same problem as @goshki ?

Gravatar
Kevin van Zonneveld
16 Jun '08 Permalink

q  @ goshki: You're right, it seems that our current version doesn't support associative arrays (javascript objects). Since PHP doesn't distinct those, we need to work on a version that does support objects. It's on my todo list. Thank your for noticing!

Gravatar
goshki
13 Jun '08 Permalink

q   Well, there seems to be some kind of a problem with this function. Running:

1
array_unique(['a','b','c','a','b','c','a','b','c']);


returns:

1
['a','a','b','c']

Gravatar
Kevin van Zonneveld
2 May '08 Permalink

q  @ duncan: You were not being stupid, we were. Thank you for noticing! The fixed version will be visible shortly.

Gravatar
duncan
30 Apr '08 Permalink

q  maybe i'm being stupid, but PHP array_unique returns an array, not a boolean.
"Takes an input array and returns a new array without duplicate values."


Contribute a New function

Download

Download

There is a wide variety of packages if the default doesn't suit you.
You can also compile your own package to avoid any overhead.

Support us

spread the word:


Use any PHP function in JavaScript


These kind folks have already donated: Anonymous and Shawn Houser.
<your name here>

Click here to lend your support to: phpjs and make a donation at www.pledgie.com !

RSS

Tweets

Comments

Who uses php.js

If you use php.js, let us know and get linked.

Progress

php.js is complete for 83.7%

php.js on

Discuss php.js' future at Google Groups
Help improve php.js on github



Powered by php.js
Stats