javascript – Convert Array to Object

The Question :

573 people think this question is useful

What is the best way to convert:

['a','b','c']

to:

{
  0: 'a',
  1: 'b',
  2: 'c'
}

The Question Comments :
  • Maybe what he needs is for some duck-typing code not to think that it is an Array instance
  • Its worth pointing out that Javascript arrays are objects.
  • If anyone else is looking for a Lodash solution, consider _.keyBy (formerly _.indexBy): lodash.com/docs#keyBy
  • This is a bit confusing because arrays are objects already, but I guess the point of the question is converting the array exotic object to an ordinary object.
  • A simple way to do this with Lodash is _.toPlainObject. Ex: var myObj = _.toPlainObject(myArr)

The Answer 1

563 people think this answer is useful

ECMAScript 6 introduces the easily polyfillable Object.assign:

The Object.assign() method is used to copy the values of all enumerable own properties from one or more source objects to a target object. It will return the target object.

Object.assign({}, ['a','b','c']); // {0:"a", 1:"b", 2:"c"}

The own length property of the array is not copied because it isn’t enumerable.

Also, you can use ES6 spread syntax to achieve the same result:

{ ...['a', 'b', 'c'] }

The Answer 2

509 people think this answer is useful

With a function like this:

function toObject(arr) {
  var rv = {};
  for (var i = 0; i < arr.length; ++i)
    rv[i] = arr[i];
  return rv;
}

Your array already is more-or-less just an object, but arrays do have some “interesting” and special behavior with respect to integer-named properties. The above will give you a plain object.

edit oh also you might want to account for “holes” in the array:

function toObject(arr) {
  var rv = {};
  for (var i = 0; i < arr.length; ++i)
    if (arr[i] !== undefined) rv[i] = arr[i];
  return rv;
}

In modern JavaScript runtimes, you can use the .reduce() method:

var obj = arr.reduce(function(acc, cur, i) {
  acc[i] = cur;
  return acc;
}, {});

That one also avoids “holes” in the array, because that’s how .reduce() works.

The Answer 3

300 people think this answer is useful

You could use an accumulator aka reduce.

['a','b','c'].reduce(function(result, item, index, array) {
  result[index] = item; //a, b, c
  return result;
}, {}) //watch out the empty {}, which is passed as "result"

Pass an empty object {} as a starting point; then “augment” that object incrementally. At the end of the iterations, result will be {"0": "a", "1": "b", "2": "c"}

If your array is a set of key-value pair objects:

[{ a: 1},{ b: 2},{ c: 3}].reduce(function(result, item) {
  var key = Object.keys(item)[0]; //first property: a, b, c
  result[key] = item[key];
  return result;
}, {});

will produce: {a: 1, b: 2, c: 3}

For the sake of completeness, reduceRight allows you to iterate over your array in reverse order:

[{ a: 1},{ b: 2},{ c: 3}].reduceRight(/* same implementation as above */)

will produce: {c:3, b:2, a:1}

Your accumulator can be of any type for you specific purpose. For example in order to swap the key and value of your object in an array, pass []:

[{ a: 1},{ b: 2},{ c: 3}].reduce(function(result, item, index) {
  var key = Object.keys(item)[0]; //first property: a, b, c
  var value = item[key];
  var obj = {};
  obj[value] = key;
  result.push(obj);
  return result;
}, []); //an empty array

will produce: [{1: "a"}, {2: "b"}, {3: "c"}]

Unlike map, reduce may not be used as a 1-1 mapping. You have full control over the items you want to include or exclude. Therefore reduce allows you to achieve what filter does, which makes reduce very versatile:

[{ a: 1},{ b: 2},{ c: 3}].reduce(function(result, item, index) {
  if(index !== 0) { //skip the first item
    result.push(item);
  }
  return result;
}, []); //an empty array

will produce: [{2: "b"}, {3: "c"}]

Caution: reduce and Object.key are part of ECMA 5th edition; you should provide a polyfill for browsers that don’t support them (notably IE8).

See a default implementation by Mozilla.

The Answer 4

103 people think this answer is useful

If you’re using jquery:

$.extend({}, ['a', 'b', 'c']);

The Answer 5

66 people think this answer is useful

For completeness, ECMAScript 2015(ES6) spreading. Will require either a transpiler(Babel) or an environment running at least ES6.

console.log(
   { ...['a', 'b', 'c'] }
)

The Answer 6

48 people think this answer is useful

I’d probably write it this way (since very rarely I’ll not be having the underscorejs library at hand):

var _ = require('underscore');

var a = [ 'a', 'b', 'c' ];
var obj = _.extend({}, a);
console.log(obj);
// prints { '0': 'a', '1': 'b', '2': 'c' }

The Answer 7

31 people think this answer is useful

Surprised not to see –

console.log(
  Object.assign({}, ['a', 'b', 'c'])
)

The Answer 8

27 people think this answer is useful

Here is an O(1) ES2015 method just for completeness.

var arr = [1, 2, 3, 4, 5]; // array, already an object
Object.setPrototypeOf(arr, Object.prototype); // now no longer an array, still an object

The Answer 9

26 people think this answer is useful

we can use Object.assign and array.reduce function to convert an Array to Object.

var arr = [{a:{b:1}},{c:{d:2}}] 
var newObj = arr.reduce((a, b) => Object.assign(a, b), {})

console.log(newObj)

The Answer 10

20 people think this answer is useful

I ended up using object spread operator, since it is part of the ECMAScript 2015 (ES6) standard.

const array = ['a', 'b', 'c'];
console.log({...array});
// it outputs {0:'a', 1:'b', 2:'c'}

Made the following fiddle as an example.

The Answer 11

18 people think this answer is useful
Object.assign({}, ['one', 'two']); // {0: 'one', 1: 'two'}

Easy way in modern JavaScript is to use Object.assign() that does nothing but copying key:value from one object to another. In our case, Array donates properties to new {}.

The Answer 12

15 people think this answer is useful

For ES2016, spread operator for objects. Note: This is after ES6 and so transpiler will need to be adjusted.

const arr = ['a', 'b', 'c'];
const obj = {...arr}; // -> {0: "a", 1: "b", 2: "c"} 

The Answer 13

13 people think this answer is useful

Using javascript#forEach one can do this

var result = {},
    attributes = ['a', 'b','c'];

attributes.forEach(function(prop,index) {
  result[index] = prop;
});

With ECMA6:

attributes.forEach((prop,index)=>result[index] = prop);

The Answer 14

12 people think this answer is useful

Five years later, there’s a good way 🙂

Object.assign was introduced in ECMAScript 2015.

Object.assign({}, ['a', 'b', 'c'])
// {'0':'a', '1':'b', '2':'c'}

The Answer 15

12 people think this answer is useful

FWIW, one another recent approach is to use the new Object.fromEntries along with Object.entries as follows:

const arr = ['a','b','c'];
arr[-2] = 'd';
arr.hello = 'e';
arr.length = 17;
const obj = Object.fromEntries(Object.entries(arr));

…which allows for avoiding storing sparse array items as undefined or null and preserves non-index (e.g., non-positive-integer/non-numeric) keys.

{ 0: “a”, 1: “b”, 2: “c”, “-2”: “d”, hello: “e” }

(Same result here as with @Paul Draper’s Object.assign answer.)

One may wish to add arr.length, however, as that is not included:

obj.length = arr.length;

The Answer 16

10 people think this answer is useful

you can use spread operator

x = [1,2,3,10]
{...x} // {0:1, 1:2, 2:3, 3:10}

The Answer 17

9 people think this answer is useful

If you’re using ES6, you can use Object.assign and the spread operator

{ ...['a', 'b', 'c'] }

If you have nested array like

var arr=[[1,2,3,4]]
Object.assign(...arr.map(d => ({[d[0]]: d[1]})))

The Answer 18

5 people think this answer is useful

A quick and dirty one:

var obj = {},
  arr = ['a','b','c'],
  l = arr.length; 

while( l &amp;&amp; (obj[--l] = arr.pop() ) ){};

The Answer 19

4 people think this answer is useful

As of Lodash 3.0.0 you can use _.toPlainObject

var obj = _.toPlainObject(['a', 'b', 'c']);
console.log(obj);
<script src="https://cdn.jsdelivr.net/lodash/4.16.4/lodash.min.js"></script>

The Answer 20

4 people think this answer is useful

A simple and cheeky method of quickly converting an Array of items in to an Object

function arrayToObject( srcArray ){
    return  JSON.parse( JSON.stringify( srcArray ) );
}

Then using it like so…

var p = [0,2,3,'pork','pie',6];
obj = new arrayToObject( p );
console.log( obj[3], obj[4] )
// expecting `pork pie`

Output:

pork pie

Checking the type:

typeof obj
"object"

AND things wouldn’t be complete if there wasn’t a prototype method

Array.prototype.toObject =function(){
    return  JSON.parse( JSON.stringify( this ) );
}

Using like:

var q = [0,2,3,'cheese','whizz',6];
obj = q.toObject();
console.log( obj[3], obj[4] )
// expecting `cheese whizz`

Output:

cheese whizz

*NOTE that there is no naming routine, so if you want to have specific names, then you will need to continue using the existing methods below.


Older method

This allows you to generate from an array an object with keys you define in the order you want them.

Array.prototype.toObject = function(keys){
    var obj = {};
    var tmp = this; // we want the original array intact.
    if(keys.length == this.length){
        var c = this.length-1;
        while( c>=0 ){
            obj[ keys[ c ] ] = tmp;
            c--;
        }
    }
    return obj;
};

result = ["cheese","paint",14,8].toObject([0,"onion",4,99]);

console.log(">>> :" + result.onion); will output “paint”, the function has to have arrays of equal length or you get an empty object.

Here is an updated method

Array.prototype.toObject = function(keys){
    var obj = {};
    if( keys.length == this.length)
        while( keys.length )
            obj[ keys.pop() ] = this[ keys.length ];
    return obj;
};

The Answer 21

4 people think this answer is useful

Quick and dirty #2:

var i = 0
  , s = {}
  , a = ['A', 'B', 'C'];

while( i < a.length ) { s[i] = a[i++] };

The Answer 22

3 people think this answer is useful

Here’s a recursive function I just wrote. It’s simple and works well.

// Convert array to object
var convArrToObj = function(array){
    var thisEleObj = new Object();
    if(typeof array == "object"){
        for(var i in array){
            var thisEle = convArrToObj(array[i]);
            thisEleObj[i] = thisEle;
        }
    }else {
        thisEleObj = array;
    }
    return thisEleObj;
}

Here’s an example (jsFiddle):

var array = new Array();
array.a = 123;
array.b = 234;
array.c = 345;
var array2 = new Array();
array2.a = 321;
array2.b = 432;
array2.c = 543;
var array3 = new Array();
array3.a = 132;
array3.b = 243;
array3.c = 354;
var array4 = new Array();
array4.a = 312;
array4.b = 423;
array4.c = 534;
var array5 = new Array();
array5.a = 112;
array5.b = 223;
array5.c = 334;

array.d = array2;
array4.d = array5;
array3.d = array4;
array.e = array3;


console.log(array);

// Convert array to object
var convArrToObj = function(array){
    var thisEleObj = new Object();
    if(typeof array == "object"){
        for(var i in array){
            var thisEle = convArrToObj(array[i]);
            thisEleObj[i] = thisEle;
        }
    }else {
        thisEleObj = array;
    }
    return thisEleObj;
}
console.log(convArrToObj(array));

Results: Recursive Array to Object

The Answer 23

3 people think this answer is useful
.reduce((o,v,i)=>(o[i]=v,o), {})

[docs]

or more verbose

var trAr2Obj = function (arr) {return arr.reduce((o,v,i)=>(o[i]=v,o), {});}

or

var transposeAr2Obj = arr=>arr.reduce((o,v,i)=>(o[i]=v,o), {})

shortest one with vanilla JS

JSON.stringify([["a", "X"], ["b", "Y"]].reduce((o,v,i)=>{return o[i]=v,o}, {}))
=> "{"0":["a","X"],"1":["b","Y"]}"

some more complex example

[["a", "X"], ["b", "Y"]].reduce((o,v,i)=>{return o[v[0]]=v.slice(1)[0],o}, {})
=> Object {a: "X", b: "Y"}

even shorter (by using function(e) {console.log(e); return e;} === (e)=>(console.log(e),e))

 nodejs
> [[1, 2, 3], [3,4,5]].reduce((o,v,i)=>(o[v[0]]=v.slice(1),o), {})
{ '1': [ 2, 3 ], '3': [ 4, 5 ] }

[/docs]

The Answer 24

3 people think this answer is useful

I would do this simply with Array.of(). Array of has the ability to use it’s context as a constructor.

NOTE 2 The of function is an intentionally generic factory method; it does not require that its this value be the Array constructor. Therefore it can be transferred to or inherited by other constructors that may be called with a single numeric argument.

So we may bind Array.of() to a function and generate an array like object.

function dummy(){};
var thingy = Array.of.apply(dummy,[1,2,3,4]);
console.log(thingy);

By utilizing Array.of() one can even do array sub-classing.

The Answer 25

3 people think this answer is useful

If you can use Map or Object.assign, it’s very easy.

Create an array:

const languages = ['css', 'javascript', 'php', 'html'];

The below creates an object with index as keys:

Object.assign({}, languages)

Replicate the same as above with Maps

Converts to an index based object {0 : 'css'} etc…

const indexMap = new Map(languages.map((name, i) => [i, name] ));
indexMap.get(1) // javascript

Convert to an value based object {css : 'css is great'} etc…

const valueMap = new Map(languages.map(name => [name, `${name} is great!`] ));
valueMap.get('css') // css is great

The Answer 26

2 people think this answer is useful

let i = 0;
let myArray = ["first", "second", "third", "fourth"];

const arrayToObject = (arr) =>
    Object.assign({}, ...arr.map(item => ({[i++]: item})));

console.log(arrayToObject(myArray));

Or use

myArray = ["first", "second", "third", "fourth"]
console.log({...myArray})

The Answer 27

2 people think this answer is useful

ES5 – Solution:

Using Array prototype function ‘push’ and ‘apply’ you can populate the object with the array elements.

var arr = ['a','b','c'];
var obj = new Object();
Array.prototype.push.apply(obj, arr);
console.log(obj);    // { '0': 'a', '1': 'b', '2': 'c', length: 3 }
console.log(obj[2]); // c

The Answer 28

2 people think this answer is useful

More browser supported and more flexible way of doing that is using a normal loop, something like:

const arr = ['a', 'b', 'c'],
obj = {};

for (let i=0; i<arr.length; i++) {
   obj[i] = arr[i];
}

But also the modern way could be using the spread operator, like:

{...arr}

Or Object assign:

Object.assign({}, ['a', 'b', 'c']);

Both will return:

{0: "a", 1: "b", 2: "c"}

The Answer 29

1 people think this answer is useful

You could use a function like this:

var toObject = function(array) {
    var o = {};
    for (var property in array) {
        if (String(property >>> 0) == property &amp;&amp; property >>> 0 != 0xffffffff) {
            o[i] = array[i];
        }
    }
    return o;
};

This one should handle sparse arrays more efficiently.

The Answer 30

1 people think this answer is useful

Here’s a solution in coffeescript

arrayToObj = (arr) ->
  obj = {}
  for v,i in arr
    obj[i] = v if v?
  obj

Add a Comment