67

I cannot find the JavaScript equivalent of PHP array_keys() / array_values().

For people unfamiliar with PHP given the following JavaScript hash:

var myHash = {"apples": 3, "oranges": 4, "bananas": 42}

How can I get an array of keys, i.e.,

["apples", "oranges", "bananas"]

The same question with the values, i.e.,

[3, 4, 42]

jQuery can be used.

1

9 Answers 9

89

In ES5 supported (or shimmed) browsers...

var keys = Object.keys(myHash);

var values = keys.map(function(v) { return myHash[v]; });

Shims from MDN...

Sign up to request clarification or add additional context in comments.

6 Comments

@greg0ire: Supported browsers are generally any modern browser. Generally most Chrome and Safari in use, Firefox 4+, Opera 10+ (maybe earlier?), and IE9. You can easily shim both of these methods to support legacy browsers.
@greg0ire: I added links to the shims provided by MDN.
Very good solution, but the code should be compatible with IE7-8 if possible.
@greg0ire: Including the linked shims will make it compatible, but if you don't want those, then IE7/8 won't work.
|
53
var a = {"apples": 3, "oranges": 4, "bananas": 42};    

var array_keys = new Array();
var array_values = new Array();

for (var key in a) {
    array_keys.push(key);
    array_values.push(a[key]);
}

alert(array_keys);
alert(array_values);

12 Comments

+1, However the inside of the for loop should be wrapped in a check that the current key is actually the Object in question's own property (as opposed to an inherited property). Else, in IE, you can get some unexpected keys: if (Object.prototype.hasOwnProperty.call(a, key)) {array_keys.push(key);array_values.push(a[key]);}
@JAAulde: I don't know of any such IE issue. when enumerating an object. Could you give a further description of that issue? What keys will be found?
@amnotiam Crockford recommends it in his LINT instructions at JSLint.com/lint.html#forin and references an article he wrote on the matter at yuiblog.com/blog/2006/09/26/for-in-intrigue
@JAAulde The members in Object.prototype should be marked as non-enumerable and skipped by the "foreach", but yes, I believe older IE could actually have problem with this. Thx.
@JAAulde: To be honest, I don't really care what Crockford recommends. There isn't an IE issue that I'm aware of. The only issue is with adding enumerable properties to Object.prototype, which is easily solvable/reversable.
|
15

The second answer (at the time of writing) gives:

var values = keys.map(function(v) { return myHash[v]; });

But I prefer using jQuery's own $.map:

var values = $.map(myHash, function(v) { return v; });

Since jQuery takes care of cross-browser compatibility. Plus it's shorter :)

At any rate, I always try to be as functional as possible. One-liners are nicers than loops.

Comments

13

Look at the _.keys() and _.values() functions in either Lodash or Underscore.js:

Comments

4
function getKeys(obj){
    var keys = [];
    for (key in obj) {
        if (obj.hasOwnProperty(key)) { keys[keys.length] = key; }
    } 
    return keys;
}

Comments

2

I don't know if it helps, but the "foreach" goes through all the keys:

for (var key in obj1) {...}

1 Comment

Watch out for "jquery/prototype"-style objects: these libraries add different functions to all the objects which are being iterated through as if they were keys too... In this case you want to use the Object.each() function provided by the given library: api.jquery.com/jQuery.each A little off topic, but somewhat important...
1

Here are implementations from phpjs.org:

This is not my code. I'm just pointing you to a useful resource.

1 Comment

The functions you're showing seem to return hashes instead of arrays or is {0: "test"} a synonym for ["test"]?
1

Use:

var myHash = {"apples": 3, "oranges": 4, "bananas": 42}
vals=(function(e){a=[];for (var i in e) a.push(e[i]); return a;})(myHash).join(',')
keys=(function(e){a=[];for (var i in e) a.push(  i ); return a;})(myHash).join(',')
console.log(vals,keys)

Basically:

array=(function(e){a=[];for (var i in e) a.push(e[i]); return a;})(HASHHERE)

Comments

-1

Here is a good example of array_keys from PHP.js library:

function array_keys (input, search_value, argStrict) {
    // Return just the keys from the input array, optionally only for the specified search_value

    var search = typeof search_value !== 'undefined',
        tmp_arr = [],
        strict = !!argStrict,
        include = true,
        key = '';

    for (key in input) {
        if (input.hasOwnProperty(key)) {
            include = true;
            if (search) {
                if (strict && input[key] !== search_value) {
                    include = false;
                }
                else if (input[key] != search_value) {
                    include = false;
                }
            }

            if (include) {
                tmp_arr[tmp_arr.length] = key;
            }
        }
    }

    return tmp_arr;
}

The same goes for array_values (from the same PHP.js library):

function array_values (input) {
    // Return just the values from the input array

    var tmp_arr = [],
        key = '';

    for (key in input) {
        tmp_arr[tmp_arr.length] = input[key];
    }

    return tmp_arr;
}

5 Comments

The functions you're showing seem to return hashes instead of arrays or is {0: "test"} a synonym for ["test"]?
@greg0ire They are not synonymous. {0: "test"} is an instance of Object, while ["test"] is an instance of Array. But both of them have member 0 of value "test".
There are objects and arrays in JavaScript. Hash you are talking about is an object. If you have a look at the line with var tmp_arr = [], it shows that tmp_arr variable is an array ([]) but not an object ({}). So both methods return arrays.
I was saying that because your functions seem to be the same as what Surreal Dreams proposed, and the links he gives say that both functions should return hashes.
This is because functions provided by PHP.js use internal methods keys() and values() that might return objects, since for JavaScript iteration { 0 : 'a', 1 : 'b' } and ['a', 'b'] are the same. I have updated the functions above so that they will return arrays only.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.