2

Say for example I had an object map of the following:

{
    "key1" : { data: "data1", extra: "none" },
    "key2" : { data: "data2", extra: "none" },
    "key3" : { data: "data3", extra: "none" },
    "key4" : { data: "data4", extra: "none" }, 
};

Is there a convenient way to convert it to a multidimesional array something like this:

[
    [ "key1" , { data: "data1", extra: "none" } ],
    [ "key2" , { data: "data2", extra: "none" } ],
    [ "key3" , { data: "data3", extra: "none" } ],
    [ "key4" , { data: "data4", extra: "none" } ], 
];

I have a function that requires an array, yet the data I'm receiving from a 3rd party plugin is in object arrays. It would be nice if there was some simple way to get the conversion done between the two.

dk123
  • 18,684
  • 20
  • 70
  • 77

3 Answers3

5

Try this function:

function convert(original) {
    var multiArray = [];
    for(var key in original) { multiArray.push([ key, original[key] ]); }
    return multiArray;
}

See demo fiddle.

Use it like this:

var myObject = {
    "key1" : { data: "data1", extra: "none" },
    "key2" : { data: "data2", extra: "none" },
    "key3" : { data: "data3", extra: "none" },
    "key4" : { data: "data4", extra: "none" }, 
};
var myMultiArray = convert(myObject);
acdcjunior
  • 132,397
  • 37
  • 331
  • 304
  • 1
    You could just use `for (var i in original)`, since `for ... in` is for object keys. – Barmar May 18 '13 at 06:48
  • @JanDvorak you are right, I overlooked it. Just improved. Thanks! – acdcjunior May 18 '13 at 06:51
  • Better now :-) Note that you're still assuming that noone has extended `Object.prototype` (but that's a safe assumption to make). – John Dvorak May 18 '13 at 06:55
  • @JanDvorak Curious. In the current code? Where am I making that assumption, exactly? – acdcjunior May 18 '13 at 06:56
  • @acdcjunior when you do `for(i in x)`, it iterates over _all_ enumerable properties of `x`, including those in the prototype chain. When you do `Object.prototype.bind = function(){...}`, every object has an enumerable property called `bind`, that this loop will return. When you do it, you break jQuery, too. – John Dvorak May 18 '13 at 07:00
  • @JanDvorak alright, I think I got it (I had to google it a bit, I admit). Thanks again, that's high level knowledge! – acdcjunior May 18 '13 at 07:21
  • Thanks for the reply, I've chosen this as my accepted answer as it 1. works across all major browsers, 2. easy to understand. Thanks! – dk123 May 19 '13 at 17:27
3

If you make a helper function pair like below, then the standard keys/map is good enough:

Object.keys(m).map(pair.bind(m))
function pair(x){return [x, this[x]]}
geocar
  • 9,085
  • 1
  • 29
  • 37
3

In ES6 it's as easy as [[e, o[e]] for (e in o)].

Neil
  • 54,642
  • 8
  • 60
  • 72
  • +1 Thanks, this really looks amazing. I chose geocar's answer in the end due to current lack of general support for ES6. Great answer though, it really makes me look forward to the capabilities of what's coming! – dk123 May 19 '13 at 17:06
  • @neil This fails in 2017 (chromium/firefox). Are you sure it‘s going to work like this? – undko Mar 25 '17 at 22:14
  • @undko Sadly it was only a proposal and didn't make ES6 in the end. The latest proposal is `[...Object.entries(o)]` which I think works in current Firefox/Chrome. – Neil Mar 26 '17 at 00:42
  • @neil Thanks! A bit more verbose, but still a big improvement compared to loops :-) – undko Mar 26 '17 at 09:43