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) {...}
Author by
greg0ire
favorite tools : git, zsh, sass favorite frameworks: Symfony* favorite languages: php, python
Updated on July 08, 2022Comments
-
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 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 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 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 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 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 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 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 about 12 years@JAAulde: Please then tell me what properties will be encountered in IE from enumerating an object created from literal notation?
-
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 about 12 yearsThe functions you're showing seem to return hashes instead of arrays or is {0: "test"} a synonym for ["test"]?
-
greg0ire about 12 yearsThe functions you're showing seem to return hashes instead of arrays or is {0: "test"} a synonym for ["test"]?
-
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 usingfor
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 about 12 years@greg0ire They are not synonymous.
{0: "test"}
is an instance ofObject
, while["test"]
is an instance ofArray
. But both of them have member0
of value"test"
. -
VisioN about 12 yearsThere 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 thattmp_arr
variable is an array ([]
) but not an object ({}
). So both methods return arrays. -
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 about 12 yearsI 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 about 12 yearsThis is because functions provided by PHP.js use internal methods
keys()
andvalues()
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 about 12 yearsWatch 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 over 9 yearsI had to use
for (var key in Object.keys(a)) {