[javascript] Convert Array to Object

What is the best way to convert:

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

to:

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

This question is related to javascript arrays node.js object

The answer is


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.


Here's a solution in coffeescript

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

maybe if you want array value to be your object key too

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

A more OO approach:

Array.prototype.toObject = function() {
 var Obj={};

 for(var i in this) {
  if(typeof this[i] != "function") {
   //Logic here
   Obj[i]=this[i];
  }
 }

 return Obj;
}

I have faced this issue multiple times and decided to write a function that is as generic as possible. Have a look and feel free to modify anything

function typeOf(obj) {
    if ( typeof(obj) == 'object' ) {
        if (obj.length)
            return 'array';
        else
            return 'object';
    } else
    return typeof(obj);
}

function objToArray(obj, ignoreKeys) {
    var arr = [];
    if (typeOf(obj) == 'object') {
        for (var key in obj) {
            if (typeOf(obj[key]) == 'object') {
                if (ignoreKeys)
                    arr.push(objToArray(obj[key],ignoreKeys));
                else
                    arr.push([key,objToArray(obj[key])]);
            }
            else
                arr.push(obj[key]);
        }
    }else if (typeOf(obj) == 'array') {
        for (var key=0;key<obj.length;key++) {
            if (typeOf(obj[key]) == 'object')
                arr.push(objToArray(obj[key]));
            else
                arr.push(obj[key]);
        }
    }
    return arr;
}

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];
            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;
};

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

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


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

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 {}.


Use the javascript lodash library. There is a simple method _.mapKeys(object, [iteratee=_.identity]) that can do the conversion.


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' }

If you like oneliners, and IE8 is not a problem anymore (as it should be)

['a','b','c'].reduce((m,e,i) => Object.assign(m, {[i]: e}), {});

Go ahead and try it on the browser console

It coult be more verbose like this:

['a','b','c'].reduce(function(memo,elm,idx) {
    return Object.assign(memo, {[idx]: elm});
}, {});

But still rules out IE8. If IE8 is a must, then you can use lodash/underscore like that:

_.reduce(['a','b','c'], function(memo,elm,idx) {
    return Object.assign(memo, {[idx]: elm});
}, {})

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.


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'}

Below method would convert array to object with particular given key.

    /**
     * Converts array to object
     * @param  {Array} array
     * @param  {string} key (optional)
     */
    Array.prototype.ArrayToObject = function(key) {
       const array = this;
       const obj = {};

       array.forEach((element, index) => {
           if(!key) {
              obj[index] = element;
           } else if ((element && typeof element == 'object' && element[key])) {
              obj[element[key]] = element;
           }
       });
    return obj;
    }

For Ex -

[{name: 'test'}, {name: 'test1'}].ArrayToObject('name');

would give

{test: {name: 'test'}, test1: {name: 'test1'}}

and incase key is not provided as param to the method

i.e. [{name: 'test'}, {name: 'test1'}].ArrayToObject();

would give

{0: {name: 'test'}, 1: {name: 'test1'}}

Quick and dirty #2:

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

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

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


A quick and dirty one:

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

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

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.

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

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


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

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


ES5 - Solution:

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

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


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

.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]


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]})))

As of Lodash 3.0.0 you can use _.toPlainObject

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


If you're using jquery:

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

_x000D_
_x000D_
let i = 0;_x000D_
let myArray = ["first", "second", "third", "fourth"];_x000D_
_x000D_
const arrayToObject = (arr) =>_x000D_
    Object.assign({}, ...arr.map(item => ({[i++]: item})));_x000D_
_x000D_
console.log(arrayToObject(myArray));
_x000D_
_x000D_
_x000D_

Or use

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


you can use spread operator

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

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.


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

initial array and will convert into an Object with keys which will be the unique element of an array and the keys value will be how many times the perticular keys will be repeating

_x000D_
_x000D_
var jsTechs = ['angular', 'react', 'ember', 'vanilaJS', 'ember', 'angular', 'react', 'ember', 'vanilaJS', 'angular', 'react', 'ember', 'vanilaJS', 'ember', 'angular', 'react', 'ember', 'vanilaJS', 'ember', 'angular', 'react', 'ember', 'vanilaJS', 'ember', 'react', 'react', 'vanilaJS', 'react', 'vanilaJS', 'vanilaJS']_x000D_
_x000D_
var initialValue = {_x000D_
  java : 4_x000D_
}_x000D_
_x000D_
var reducerFunc = function reducerFunc (initObj, jsLib) {_x000D_
  if (!initObj[jsLib]) {_x000D_
    initObj[jsLib] = 1_x000D_
  } else {_x000D_
    initObj[jsLib] += 1_x000D_
  }_x000D_
  return initObj_x000D_
}_x000D_
var finalResult = jsTechs.reduce(reducerFunc, initialValue)_x000D_
console.log(finalResult)
_x000D_
_x000D_
_x000D_


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;

My version array to json in JS. Jusy copy/paste and use it. Isn't this awesome? I love this type of functions I found on StackOverflow.

function array2json(arr) {
    var parts = [];
    var is_list = (Object.prototype.toString.apply(arr) === '[object Array]');

    for(var key in arr) {
        var value = arr[key];
        if(typeof value == "object") { //Custom handling for arrays
            if(is_list) parts.push(array2json(value)); /* :RECURSION: */
            else parts[key] = array2json(value); /* :RECURSION: */
        } else {
            var str = "";
            if(!is_list) str = '"' + key + '":';

            //Custom handling for multiple data types
            if(typeof value == "number") str += value; //Numbers
            else if(value === false) str += 'false'; //The booleans
            else if(value === true) str += 'true';
            else str += '"' + value + '"'; //All other things
            // :TODO: Is there any more datatype we should be in the lookout for? (Functions?)

            parts.push(str);
        }
    }
    var json = parts.join(",");

    if(is_list) return '[' + json + ']';//Return numerical JSON
    return '{' + json + '}';//Return associative JSON
}

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"}

_x000D_
_x000D_
var finalResult = ['a','b','c'].map((item , index) => ({[index] : item}));_x000D_
console.log(finalResult)
_x000D_
_x000D_
_x000D_


Surprised not to see -

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


It's not directly relevant but I came here searching for a one liner for merging nested objects such as

const nodes = {
    node1: {
        interfaces: {if1: {}, if2: {}}
    },
    node2: {
        interfaces: {if3: {}, if4: {}}
    },
    node3: {
        interfaces: {if5: {}, if6: {}}
    },
}

The solution is to use a combination of reduce and object spread:

const allInterfaces = nodes => Object.keys(nodes).reduce((res, key) => ({...res, ...nodes[key].interfaces}), {})

I would use underscore for this, but if that isn't available then I would drop down to using reduce with an initial value of empty object {}

>>> ['a', 'b', 'c'].reduce(function(p, c, i) {p[i] = c; return p}, {})
Object { 0="a", 1="b", 2="c"}

reduce should be widely available in most browsers today, see MDN


If you are using angularjs you can use angular.extend, the same effect with $.extend of jquery.

var newObj = {};
angular.extend(newObj, ['a','b','c']);

It is easy to use javascript reduce:

["a", "b", "c", "d"].reduce(function(previousValue, currentValue, index) { 
   previousValue[index] = currentValue; 
   return previousValue;
}, 
{}
);

You can take a look at Array.prototype.reduce(), https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/Reduce


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

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


You could use a function like this:

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

This one should handle sparse arrays more efficiently.


Try using reflect to copy from array item to object.

var arr =['aa:23','bb:44','cc:55']
    var obj ={}
    arr.forEach(e => {
        var ee = e.split(':')
        Reflect.set(obj,ee[0],ee[1])
    });
    console.log(obj) // { aa: '23', bb: '44', cc: '55' }

Simplest way to do this is the following:

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

function ConvertArr(arr) { 
 if (typeof(arr) === 'array') {
 Object.assign(obj, arr);
}

This way it only runs if it is an array, however, you can run this with let global object variable or without, that's up to you, if you run without let, just do Object.assign({}, arr).


Examples related to javascript

need to add a class to an element How to make a variable accessible outside a function? Hide Signs that Meteor.js was Used How to create a showdown.js markdown extension Please help me convert this script to a simple image slider Highlight Anchor Links when user manually scrolls? Summing radio input values How to execute an action before close metro app WinJS javascript, for loop defines a dynamic variable name Getting all files in directory with ajax

Examples related to arrays

PHP array value passes to next row Use NSInteger as array index How do I show a message in the foreach loop? Objects are not valid as a React child. If you meant to render a collection of children, use an array instead Iterating over arrays in Python 3 Best way to "push" into C# array Sort Array of object by object field in Angular 6 Checking for duplicate strings in JavaScript array what does numpy ndarray shape do? How to round a numpy array?

Examples related to node.js

Hide Signs that Meteor.js was Used Querying date field in MongoDB with Mongoose SyntaxError: Cannot use import statement outside a module Server Discovery And Monitoring engine is deprecated How to fix ReferenceError: primordials is not defined in node UnhandledPromiseRejectionWarning: This error originated either by throwing inside of an async function without a catch block dyld: Library not loaded: /usr/local/opt/icu4c/lib/libicui18n.62.dylib error running php after installing node with brew on Mac internal/modules/cjs/loader.js:582 throw err DeprecationWarning: Buffer() is deprecated due to security and usability issues when I move my script to another server Please run `npm cache clean`

Examples related to object

How to update an "array of objects" with Firestore? how to remove json object key and value.? Cast object to interface in TypeScript Angular 4 default radio button checked by default How to use Object.values with typescript? How to map an array of objects in React How to group an array of objects by key push object into array Add property to an array of objects access key and value of object using *ngFor