Use PHP functions in JavaScript

JavaScript array_intersect_key

Returns the entries of arr1 that have keys which are present in all the other arguments. Kind of equivalent to array_diff(array_keys($arr1), array_keys($arr2)[,array_keys(...)]). Equivalent of array_intersect_assoc() but does not do compare of the data.

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
function array_intersect_key () {
    // Returns the entries of arr1 that have keys which are present in all the other arguments. Kind of equivalent to array_diff(array_keys($arr1), array_keys($arr2)[,array_keys(...)]). Equivalent of array_intersect_assoc() but does not do compare of the data.  
    // 
    // version: 909.322
    // discuss at: http://phpjs.org/functions/array_intersect_key    // +   original by: Brett Zamir (http://brett-zamir.me)
    // %        note 1: These only output associative arrays (would need to be
    // %        note 1: all numeric and counting from zero to be numeric)
    // *     example 1: $array1 = {a: 'green', b: 'brown', c: 'blue', 0: 'red'}
    // *     example 1: $array2 = {a: 'green', 0: 'yellow', 1: 'red'}    // *     example 1: array_intersect_key($array1, $array2)
    // *     returns 1: {0: 'red', a: 'green'}
    var arr1 = arguments[0], retArr = {};
    var k1 = '', arr = {}, i = 0, k = '';
     arr1keys:
    for (k1 in arr1) {
        arrs:
        for (i=1; i < arguments.length; i++) {
            arr = arguments[i];            for (k in arr) {
                if (k === k1) {
                    if (i === arguments.length-1) {
                        retArr[k1] = arr1[k1];
                    }                    // If the innermost loop always leads at least once to an equal value, continue the loop until done
                    continue arrs;
                }
            }
            // If it reaches here, it wasn't found in at least one array, so try next value            continue arr1keys;
        }
    }
 
    return retArr;}
external links: original PHP docs | raw js source

Examples

Running

1
2
3
$array1 = {a: 'green', b: 'brown', c: 'blue', 0: 'red'}
$array2 = {a: 'green', 0: 'yellow', 1: 'red'}
array_intersect_key($array1, $array2)

Should return

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

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_intersect_key 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
11 Aug '09 Permalink

q  Sorry again, but my reply is mistaken as well. And it will all really depend on whether you are trying to build a return array which returns all of the keys shared across arrays based on the first one, and those subkeys which are shared as well, or if you want to ensure that those whose keys match across all arrays must also, if they are objects, have subkeys which are also contained across all arrays (or otherwise not include them)...

Gravatar
Brett Zamir
11 Aug '09 Permalink

q   Sorry, I realized the long 'if' should be changed to this to account for null values:

1
if (i === arguments.length-1 && (typeof arr1[k1] !== 'object' || typeof arr1[k1] === null || ct(arr[k]) === ct(  this.array_intersect_key_recursive.apply(this, tempArr)))) {

Gravatar
Brett Zamir
11 Aug '09 Permalink

q   @Jean Marie: Glad to hear it fit your needs... Since there is otherwise no reasonable way for us to represent associative arrays in JavaScript, the PHP.JS project generally considers objects to be as arrays. As far as your question, I am guessing you want to ensure that only those keys are returned where there is a perfect match, including any subkeys? Here is a recursive version that seems to work for this:

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
var_dump(
    array_intersect_key_recursive({a:3, b:{c:5, d:5}, q:{r:5}}, {a:'z', c:'y', b:{c:6, d:8}, q:{s:5}})
);
 
function array_intersect_key_recursive () {    var arr1 = arguments[0], retArr = {};
    var k1 = '', arr = {}, i = 0, k = '';
    var ct = function (obj) {
        var c = 0;
        for (var p in obj) {            c++;
        }
        return c;
    };
    arr1keys:    for (k1 in arr1) {
        var tempArr = [arr1[k1]];
        arrs:
        for (i=1; i < arguments.length; i++) {
            arr = arguments[i];            for (k in arr) {
                if (k === k1) {
                    tempArr.push(arr[k]);
                    if (i === arguments.length-1 && (typeof arr1[k1] !== 'object' || ct(arr[k]) === ct(  this.array_intersect_key_recursive.apply(this, tempArr)))) {
                        retArr[k1] = arr1[k1];                    }
                    // If the innermost loop always leads at least once to an equal value, continue the loop until done
                    continue arrs;
                }
            }            // If it reaches here, it wasn't found in at least one array, so try next value
            continue arr1keys;
        }
    }
    return retArr;}

Gravatar
Jean Marie
11 Aug '09 Permalink

q  Hi,

nice function i was looking for. Thanks!

Two points to mention:
1) You're not handling arrays! It should be named object_intersect_key().

2) Is it possible to get this working in recursive.


Best regards
Jean Marie


Contribute a New function