1

Is there a more succinct way of moving all array indices and values to an object than this:

arr = ["one","two","three"];
var rv = {};
for (var i = 0; i < arr.length; i++)
    rv[i] = arr[i];

I know you can iterate over the array and add to a new object one by one, but I hate adding a loop to my code whenever I want to switch between the two, particularly when providing answers here on SO (note that this means making a function is out, because this would bloat an answer just as much).

PS: I don't mind if your answer is frowned upon or is a misuse of a language feature, JS hackery fascinates me anyway. :)

Asad Saeeduddin
  • 46,193
  • 6
  • 90
  • 139
  • 2
    Arrays are objects too ;) What are you trying to achieve with this? What do you gain from having a "plain" object instead of an array? – Felix Kling Nov 21 '12 at 07:19
  • @FelixKling When someone asks a question where the desired output is an object, I prefer not to provide something that has a bunch of extra prototype properties attached (and shows up in the console as `[ ]`). I agree, there isn't really a functional difference besides the fact that some key names are already taken. – Asad Saeeduddin Nov 21 '12 at 07:25
  • Then why do you use an array to begin with? Most of the time it is clear whether an array or an object is more appropriate. – Felix Kling Nov 21 '12 at 07:29
  • @FelixKling Well, the problem is that an array is easier to obtain than an object for equivalent data. For example, you have the native `split` method to get the chunks of a string as an array, but getting the same as an object isn't possible. – Asad Saeeduddin Nov 21 '12 at 07:33
  • @Asad: I don't recall an API I've had to call that wanted me to provide it with a non-Array object with keys like `"0"`, `"1"`, etc. I'm just not getting the use case here... – T.J. Crowder Nov 21 '12 at 07:34
  • @T.J.Crowder Well here's the specific answer that sparked this: http://stackoverflow.com/a/13487726/1726343. The use case is pretty narrow now I think about it.\ – Asad Saeeduddin Nov 21 '12 at 07:36
  • @Asad: But...there, they specifically *ask* for an array. And you're giving them one. So....? – T.J. Crowder Nov 21 '12 at 07:41
  • @T.J.Crowder No he's asking for an object, with keys `var1`,`var2` etc. He just mistook it for an array (I thought). What I did was use an additional `forEach` to remove each index, split it, and re-add it as a key value pair, but the end result was still just a zero length array with a bunch of extra properties. Anyway, silly question I guess. – Asad Saeeduddin Nov 21 '12 at 07:51
  • @Asad: Well, your accepted answer to this question won't convert an array to an object with properties `var1`, `var2`, etc., either. :-) – T.J. Crowder Nov 21 '12 at 08:04

3 Answers3

3

Is there a succinct way of moving all array indices and values to an object as key value pairs?

They already are. Arrays in JavaScript are just objects, with properties named for the array indexes. They aren't really arrays at all in the classic computer science sense.

So you may well find that you don't need to do this most of the time. (Your use cases for it would be interesting.) But when you do, no, there's no particular shortcut. It's going to be a loop whatever you do, whether it's a loop in your code right out in the open, or something hidden underneath. Your code for doing it seems likely to be as good as any other.

T.J. Crowder
  • 1,031,962
  • 187
  • 1,923
  • 1,875
2

Here's one hacky way:

myArray.__proto__ = Object.prototype
Eric
  • 95,302
  • 53
  • 242
  • 374
  • Doesn't work, at least not on Chrome, which is to say, on V8 (so Chrome, Node, etc.). `var a = [1, 2, 3]; a.__proto__ = Object.prototype; console.log(JSON.stringify(a));` still logs an array, not an object. – T.J. Crowder Nov 21 '12 at 07:22
  • @TJCrowder: does `myArray intanceof Array` give FALSE? – Eric Nov 21 '12 at 07:25
  • @ Eric: Yes, but then, `instanceof` is easily fooled. :-) It would appear that to the engine, the innate Array-ness has not been changed. The console still shows an array, etc., it's not just `JSON.stringify`. But your approach does at least make the array methods disappear (on engines like V8 and Firefox's various monkeys that support `__proto__`; not on engines like IE's that don't). – T.J. Crowder Nov 21 '12 at 07:27
1

As mentioned, arrays are objects too: typeof [] === 'object'

But anyway, try this:

function objectify(arr) {
    return arr.reduce({}, function (p, e, i) {
        p[i] = e;
        return p;
    });
}

It's not really cleaner than yours, but it avoids declaring i. For a faster function, move the anonymous function outside of objectify so it doesn't get recreated every time.

beatgammit
  • 19,817
  • 19
  • 86
  • 129