Hash keys / values as array

194,940

Solution 1

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);

Solution 2

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.

Solution 3

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

Solution 4

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

Solution 5

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

for (var key in obj1) {...}
Share:
194,940
greg0ire
Author by

greg0ire

favorite tools : git, zsh, sass favorite frameworks: Symfony* favorite languages: php, python

Updated on July 08, 2022

Comments

  • greg0ire
    greg0ire almost 2 years

    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.

  • JAAulde
    JAAulde about 12 years
    +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]);}
  • Admin
    Admin about 12 years
    @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?
  • JAAulde
    JAAulde about 12 years
    @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
  • Imp
    Imp about 12 years
    @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.
  • Admin
    Admin about 12 years
    @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.
  • JAAulde
    JAAulde about 12 years
    @Imp Yes, they should be, but as you say versions of IE have issues with it. IIRC, I have had issues with it through IE8, though it may have only been up to 7.
  • JAAulde
    JAAulde about 12 years
    @amnotiam I don't recommend because Crockford does, I recommend it because it has bit me in the ass numerous times. I link to Crockford because he does a good job of explaining it. Ignore the advice if you want, it's no matter to me. Just speaking from a lot of experience.
  • Admin
    Admin about 12 years
    @JAAulde: Please then tell me what properties will be encountered in IE from enumerating an object created from literal notation?
  • JAAulde
    JAAulde about 12 years
    @amnotiam You are correct, it doesn't happen (in my experience) when using literal notation. I am recommending a best coding practice to avoid the need to think about what kind of object you're iterating and to avoid code maint issues should the code in question ever have to iterate something different.
  • greg0ire
    greg0ire about 12 years
    The functions you're showing seem to return hashes instead of arrays or is {0: "test"} a synonym for ["test"]?
  • greg0ire
    greg0ire about 12 years
    The functions you're showing seem to return hashes instead of arrays or is {0: "test"} a synonym for ["test"]?
  • Admin
    Admin about 12 years
    @JAAulde: Yeah, that's why I don't like a lot of Crockford's recommendations. Some of them are centered around avoiding the need to think about what one is doing. There certainly are issues with using for-in against things like NodeLists, but proper iteration using for is the solution, not burdening your code with a test of every property, just so we don't need to think about what we're doing.
  • Imp
    Imp about 12 years
    @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".
  • VisioN
    VisioN about 12 years
    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.
  • JAAulde
    JAAulde about 12 years
    @amnotiam Yeah, to each their own. I consider it a future proofing rather than an "unencumbering of the thought process" (to paraphrase Click and Clack). S'All good.
  • greg0ire
    greg0ire about 12 years
    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.
  • VisioN
    VisioN about 12 years
    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.
  • Igor Deruga
    Igor Deruga about 12 years
    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...
  • jcalfee314
    jcalfee314 over 9 years
    I had to use for (var key in Object.keys(a)) {