JavaScript array_diff
Returns the entries of arr1 that have values which are not present in any of the others arguments.
1 2 3 4 56 7 8 9 1011 12 13 14 1516 17 18 19 2021 22 23 24 2526 27 28 29 | function array_diff () { // Returns the entries of arr1 that have values which are not present in any of the others arguments. // // version: 910.2514 // discuss at: http://phpjs.org/functions/array_diff // + original by: Kevin van Zonneveld (http://kevin.vanzonneveld.net) // + improved by: Sanjoy Roy // + revised by: Brett Zamir (http://brett-zamir.me) // * example 1: array_diff(['Kevin', 'van', 'Zonneveld'], ['van', 'Zonneveld']); // * returns 1: {0:'Kevin'} var arr1 = arguments[0], retArr = {}; var k1 = '', i = 1, k = '', arr = {}; arr1keys: for (k1 in arr1) { for (i = 1; i < arguments.length; i++) { arr = arguments[i]; for (k in arr) { if (arr[k] === arr1[k1]) { // If it reaches here, it was found in at least one array, so try next value continue arr1keys; } } retArr[k1] = arr1[k1]; } } return retArr; } |
Examples
Running
1 | array_diff(['Kevin', 'van', 'Zonneveld'], ['van', 'Zonneveld']); |
Should return
1 | {0:'Kevin'} |
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_diff goodness in JavaScript.
@Kevin: Now that we actually have a FAQ on the wiki (at least the beginnings of one), do you want to link directly to that instead of the wiki? (or maybe call it "FAQ/wiki" to indicate that both are available there) I think it's important to indicate that we have FAQ answered there. Also, what do you think of making automated links on the function pages to the wiki for letting users contribute their own non-PHP variations, tips on use, etc.?
It seems the comments problem is fixed now. And, sure, go ahead and add a link to the wiki; that'd be great...
@ Brett Zamir: The comments, no I'm not having those issues. Could you by any chance supply the errors?
btw I removed the social javascript. maybe that fixes some issues as well.
@ Brett Zamir: Thanks for baring with me Brett. I must say I'll sleep a little bit better knowing there's 1 less thing I need to maintain & think of.
I'll add a link to the github wiki and we'll see how it goes OK?
@Kevin: Also, by the way, do you know why phpjs.org hangs seemingly indefinitely after posting a comment here? I seem to always have to refresh the page... (there are also some red warnings displayed in the interim)
@Kevin: I guess using the GitHub wiki would be ok, but it really gets under my skin when these sites, instead of using the powerful and well-known Mediawiki, add frustratingly deficient wikis of their own (and I'm already unhappy with Git itself, or rather, the current lack of GUI tools to work with it as well as with Subversion). But to be fair to you (and it is not a big deal for the limited documentation we need), the GitHub wiki should work fine for this.
I understand, and have by now run into the problem myself (array_diff with un-indexed arrays gives forced numeric indexes to the resulting array).
If you choose to use generic Objects for arrays throughout, the implode() function should reflect this as well.
I'll append a comment there.
@ Brett Zamir: We could probably start one in the wiki.
What do you think about hosting the wiki here:
http://wiki.github.com/kvz/phpjs ?
this way i wouldn't have to worry about updating media wiki, accountmanagement, and backups ?
@Itsacon: We are really kind of forced in most cases to treat arrays as objects in order to preserve PHP-like behavior of preserving keys (such as array_diff), including numeric keys. For example, to take Example #1 at http://php.net/array_diff , note that the key returned is '1' (with the value 'blue'). To do this with a regular array, we would either need to force the array to be of size 2, i.e.: "[undefined, 'blue']" or lose the key=1 information, i.e., "['blue']".
I also see that I hadn't updated our array_diff example to show an object being returned, so it was showing an array being returned instead, but that is now fixed in Git.
If you really want to be able to return genuine arrays and don't mind losing key information (or don't mind getting an array which has "undefined" place-holders for empty numeric keys causing the size of the array to be inflated), then we could add some code to allow you to do something like:
1 | ini_set('phpjs.objectsAsArrays', 0); |
...to indicate you want array inputs to be returned as arrays. But again, there are disadvantages to this, and we'd have to choose one of the two approaches (undefined items or no key information).
@Kevin: If you ever decide to add a FAQ, I think this should be the #1 Question! :)
There's a compatibility problem with this function and functions that take Array inputs (and check for it), like implode().
This is caused by this line:
1 | var arr1 = arguments[0], retArr = {}; |
The retArr variable gets instantiated as a generic Object, not an Array. Because of this, the return value for this function is not an Array.
I changed this line to
1 | var arr1 = arguments[0], retArr = new Array; |
This solved my problems.
(Note that this also applies to several other array_ functions that (should) return Arrays)
///////////////////////////////////////////////////////////
/*
Sanjoy Roy's comments:
-------------------------------
I have added a counter variable (cntr) and return array returns ordered array.
This will help to get rid of 'undefined' values in the list when we use them in our program.
*/
//////////////////////////////////////////////////////////
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 | function array_diff (array) { // http://kevin.vanzonneveld.net // + original by: Kevin van Zonneveld (http://kevin.vanzonneveld.net) // * example 1: array_diff(['Kevin', 'van', 'Zonneveld'], ['van', 'Zonneveld']); // * returns 1: ['Kevin'] var arr_dif = [], i = 1, argc = arguments.length, argv = arguments, key, key_c, found=false, cntr=0; // loop through 1st array for ( key in array ){ // loop over other arrays for (i = 1; i< argc; i++){ // find in the compare array found = false; for (key_c in argv[i]) { if (argv[i][key_c] == array[key]) { found = true; break; } } if(!found){ //arr_dif[key] = array[key]; arr_dif[cntr] = array[key]; cntr++; } } } return arr_dif;}; |
@ Ates Goral: All together superb contributions. Greatly formatted and very consistent. I also like that you've included the example-return pairs in the comments. Thanks a LOT!
Here's array_diff_key():
1 2 3 4 56 7 8 9 1011 12 13 14 1516 17 18 19 2021 22 23 24 2526 27 28 | function array_diff_key(object) { // * example 1: array_diff_key({red: 1, green: 2, blue: 3, white: 4}); // * returns 1: {"red":1, "green":2, "blue":3, "white":4} // * example 2: array_diff_key({red: 1, green: 2, blue: 3, white: 4}, {red: 5}); // * returns 2: {"green":2, "blue":3, "white":4} // * example 3: array_diff_key({red: 1, green: 2, blue: 3, white: 4}, {red: 5}, {green: 6, blue: 7}); // * returns 3: {"white":4} // * example 4: array_diff_key({red: 1, green: 2, blue: 3, white: 4}, {red: 5}, {red: 5}); // * returns 4: {"green":2, "blue":3, "white":4} var ret = new Object(); for (var key in object) { ret[key] = object[key]; } for (var argidx = 1; argidx < arguments.length; ++argidx) { var other = arguments[argidx]; if (other instanceof Object) { for (var key in other) { delete ret[key]; } } } return ret; } |



Kevin van Zonneveld
8 Nov '09
Ok, good.
I've changed the navigation a bit according to your ideas.
As far as linking/making wiki pages for individual functions; I'm not too fond of that idea as there already is a lot of information about functions in the comments, and I think I'd like to keep it centralized that way.
And we can't move all function comments to the wiki cause that would probably raise the bar for people to leave any comment at all.