Convert Array to Object
JavascriptArraysObjectJavascript Problem Overview
What is the best way to convert:
['a','b','c']
to:
{
0: 'a',
1: 'b',
2: 'c'
}
Javascript Solutions
Solution 1 - Javascript
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 ES8 spread syntax on objects to achieve the same result:
{ ...['a', 'b', 'c'] }
For custom keys you can use reduce:
['a', 'b', 'c'].reduce((a, v) => ({ ...a, [v]: v}), {})
// { a: "a", b: "b", c: "c" }
Solution 2 - Javascript
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.
Solution 3 - Javascript
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.
Solution 4 - Javascript
If you're using jquery:
$.extend({}, ['a', 'b', 'c']);
Solution 5 - Javascript
For completeness, ECMAScript 2015(ES6) spreading. Will require either a transpiler(Babel) or an environment running at least ES6.
console.log(
{ ...['a', 'b', 'c'] }
)
Solution 6 - Javascript
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' }
Solution 7 - Javascript
In case you want to use one of the properties of the iterated objects as key, for example:
// from:
const arr = [
{
sid: 123,
name: 'aaa'
},
{
sid: 456,
name: 'bbb'
},
{
sid: 789,
name: 'ccc'
}
];
// to:
{
'123': { sid: 123, name: 'aaa' },
'456': { sid: 456, name: 'bbb' },
'789': { sid: 789, name: 'ccc' }
}
Use:
const result = arr.reduce((obj, cur) => ({...obj, [cur.sid]: cur}), {})
Solution 8 - Javascript
Surprised not to see -
console.log(
Object.assign({}, ['a', 'b', 'c'])
)
Solution 9 - Javascript
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
Solution 10 - Javascript
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)
Solution 11 - Javascript
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.
Solution 12 - Javascript
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"}
Solution 13 - Javascript
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 {}
.
Solution 14 - Javascript
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;
Solution 15 - Javascript
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);
Solution 16 - Javascript
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'}
Solution 17 - Javascript
you can use spread operator
x = [1,2,3,10]
{...x} // {0:1, 1:2, 2:3, 3:10}
Solution 18 - Javascript
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]})))
Solution 19 - Javascript
The simplest way is to use a spread operator.
var arr = ["One", "Two", 3];
var obj = {...arr};
console.log(obj);
Solution 20 - Javascript
A quick and dirty one:
var obj = {},
arr = ['a','b','c'],
l = arr.length;
while( l && (obj[--l] = arr.pop() ) ){};
Solution 21 - Javascript
Quick and dirty #2:
var i = 0
, s = {}
, a = ['A', 'B', 'C'];
while( i < a.length ) { s[i] = a[i++] };
Solution 22 - Javascript
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;
};
Solution 23 - Javascript
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"}
Solution 24 - Javascript
.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]
Solution 25 - Javascript
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>
Solution 26 - Javascript
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
Solution 27 - Javascript
If someone is searching for a Typescript method, i wrote this:
const arrayToObject = <T extends Record<K, any>, K extends keyof any>(
array: T[] = [],
getKey: (item: T) => K,
) =>
array.reduce((obj, cur) => {
const key = getKey(cur)
return ({...obj, [key]: cur})
}, {} as Record<K, T>)
It will:
- enforce first param to be array of objects
- help to select the key
- enforce the key to be an key of all array items
Example:
// from:
const array = [
{ sid: 123, name: 'aaa', extra: 1 },
{ sid: 456, name: 'bbb' },
{ sid: 789, name: 'ccc' }
];
// to:
{
'123': { sid: 123, name: 'aaa' },
'456': { sid: 456, name: 'bbb' },
'789': { sid: 789, name: 'ccc' }
}
usage:
const obj = arrayToObject(array, item => item.sid) // ok
const obj = arrayToObject(array, item => item.extra) // error
Solution 28 - Javascript
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:
Solution 29 - Javascript
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.
Solution 30 - Javascript
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})
Solution 31 - Javascript
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
Solution 32 - Javascript
Use the javascript lodash library. There is a simple method
_.mapKeys(object, [iteratee=_.identity])
that can do the conversion.
Solution 33 - Javascript
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' }
Solution 34 - Javascript
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.
Solution 35 - Javascript
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}), {})
Solution 36 - Javascript
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).
Solution 37 - Javascript
Here's a solution in coffeescript
arrayToObj = (arr) ->
obj = {}
for v,i in arr
obj[i] = v if v?
obj
Solution 38 - Javascript
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']);
Solution 39 - Javascript
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'}}
Solution 40 - Javascript
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;
}
Solution 41 - Javascript
typescript solutioin:
export const toMap = (errors: ResponseError[]) => {
const errorMap: Record<string, string> = {};
errors.forEach(({ field, message }) => {
errorMap[field] = message;
});
return errorMap;
};
export type FieldError = {
field: string;
message: string;
};
Solution 42 - Javascript
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;
}
Solution 43 - Javascript
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
Solution 44 - Javascript
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});
}, {})
Solution 45 - Javascript
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
Solution 46 - Javascript
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
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']
var initialValue = {
java : 4
}
var reducerFunc = function reducerFunc (initObj, jsLib) {
if (!initObj[jsLib]) {
initObj[jsLib] = 1
} else {
initObj[jsLib] += 1
}
return initObj
}
var finalResult = jsTechs.reduce(reducerFunc, initialValue)
console.log(finalResult)
Solution 47 - Javascript
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
}
Solution 48 - Javascript
var finalResult = ['a','b','c'].map((item , index) => ({[index] : item}));
console.log(finalResult)
Solution 49 - Javascript
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;
}