What is the best way to convert:
['a','b','c']
to:
{
0: 'a',
1: 'b',
2: 'c'
}
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" }
{ ...[sortedArray]}reduce like: arr.reduce((a, v) => ({ ...a, [v]: v}), {})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.
[]) if you're not going to use numeric property keys and the "length" property.const obj = arr.reduce((obj, cur, i) => { return { ...obj, [i]: cur }; }, {});const obj = arr.reduce((obj, cur, i) => ({ ...obj, [i]: cur }), {});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.
If you're using jquery:
$.extend({}, ['a', 'b', 'c']);
{0: 'a', 1: 'b', 2: 'c'} what is an expected result.Not many people here commented of Object.fromEntries, I really enjoy it, since it's cleaner and works easily with TypeScript, without bothering too much about generic types and stuff. It also allows custom keys with map, if needed. Cons: you'll need an additional map, if you want a custom key. E.g.:
const tags = [
{ name: 'AgeGroup', value: ageGroup },
{ name: 'ApparelTypes', value: apparelTypes },
{ name: 'Brand', value: brand },
// ...
]
const objectTags = Object.fromEntries(tags.map((t) => [t.name, t.value]))
/*
{
AgeGroup: 'Adult',
Apparel: 'Creeper, Jacket'
Brand: '',
// ...
}
*/
Object.fromEntries. This function might make it more idiomatic: Array.prototype.toObj = function(f) { return Object.fromEntries(this.map(f)) }. It can be called like this to do what the OP asked: ["a", "b", "c"].toObj((item, index) => [index, item])For completeness, ECMAScript 2015(ES6) spreading. Will require either a transpiler(Babel) or an environment running at least ES6.
console.log(
{ ...['a', 'b', 'c'] }
)
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}), {})
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' }
obj=_.extend({},a); would do the job. Also, if you are iterating through arrays I’d say _.each would be more appropriate than _.map. All in all, this is not a good answer on several levels.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)
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
length property. (3) The object is still an array, Array.isArray(arr) === true. (4) Special array behaviors are not removed, e.g. arr.length = 0 removes all indices. (5) Therefore, I think Object.assign is much better.Array.isArray is returning true for the "object" here even though instanceof Array does not...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;
arr.entries() instead of Object.entries(arr)If your array contains 2-element arrays where first element is the key and second element is the value you can easily convert to object using reduce.
[
["key1","value1"],
["key2", "value2"],
["key3", "value3"]
]
.reduce((acc, [key, value])=>({...acc, [key]: value}), {});
Result:
{
key1: 'value1',
key2: 'value2',
key3: 'value3'
}
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);
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]})))
new Map([['key1', 'value1'], ['key2', 'value2']]);A quick and dirty one:
var obj = {},
arr = ['a','b','c'],
l = arr.length;
while( l && (obj[--l] = arr.pop() ) ){};
{0:"c", 1:"b", 2:"a"}. You either want unshift instead of pop or (better) start with i=arr.length-1 and decrement instead.l = arr.length, and then while (l && (obj[--l] = arr.pop())){} (I realize this is old, but why not simplify it even further).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"}
Quick and dirty #2:
var i = 0
, s = {}
, a = ['A', 'B', 'C'];
while( i < a.length ) { s[i] = a[i++] };
i < a.length instead of a[i].Why No One try this? in ES6
let arr = ['a','b','c']
let {...obj} = arr
console.log(obj) // {0: 'a', 1: 'b', 2: 'c'}
let {...obj2} = ['a','b','c']
console.log(obj2) // {0: 'a', 1: 'b', 2: 'c'}
is Very simple way?
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;
};
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:

['a' = '1', 'b' = '2', 'c' = '3'] and want it like {a: 1, b: 2, c: 3} this works perfect..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]
[/docs]? It would be more useful to make the code snippets executable.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>
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
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.
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
{ name: a, div :b, salary:c}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:
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
${val}; }, '') }) }, {} as Record<K, T>);There are some methods available: Object.fromEntries(), reduce, forEach, Object.assign(), the spread operator ({...}) and the traditional for loop.
Object.fromEntries() performs best with few objects, while reduce(), forEach(), and for loop are more suitable for handling larger amounts of data. I will say from 1K objects you should avoid Object.fromEntries(). reduce() shows good scalability and efficiency with large datasets.
Note that Object.assign() and the spread operator ({...}) can also convert arrays to objects but have limitations with custom key mapping, making them less practical for real-world use cases.
For small data sets, use Object.fromEntries(), while for larger data sets(1K+), consider using reduce(), forEach(), or for loop. Take a look to the JS snippet below if you want to see the implementation.
// Benchmark function
function benchmark(fn) {
const start = performance.now();
fn();
const end = performance.now();
return (end - start).toFixed(2);
}
// 1. Using reduce
function benchmarkReduce(inputArr) {
return benchmark(() => {
inputArr.reduce((acc, obj) => {
acc[obj.id] = obj;
return acc;
}, {});
});
}
// 2. Using Object.fromEntries
function benchmarkFromEntries(inputArr) {
return benchmark(() => {
Object.fromEntries(inputArr.map(obj => [obj.id, obj]));
});
}
// 3. Using forEach
function benchmarkForEach(inputArr) {
return benchmark(() => {
const obj = {};
inputArr.forEach((item) => {
obj[item.id] = item;
});
});
}
// 4. Using for loop
function benchmarkLoop(inputArr) {
return benchmark(() => {
const obj = {};
for (let i = 0; i < inputArr.length; i++) {
const item = inputArr[i];
obj[item.id] = item;
}
});
}
// 5. Using Object.assign
function benchmarkObjectAssign(inputArr) {
return benchmark(() => {
Object.assign({}, inputArr);
});
}
// 6. Using Spread Operator
function benchmarkSpreadOperator(inputArr) {
return benchmark(() => {
({ ...inputArr
});
});
}
function generateMultipliers() {
const multipliers = [];
const step = 30;
for (let i = 10; i < 2000; i++) {
multipliers.push(step * (i + 1));
}
return multipliers;
}
function storeResults(results) {
const jsonString = JSON.stringify(results, null, 2);
const blob = new Blob([jsonString], {
type: 'application/json'
});
const link = document.createElement('a');
link.href = URL.createObjectURL(blob);
link.download = 'results.json';
document.body.appendChild(link);
link.click();
document.body.removeChild(link);
}
async function executeBenchmarks() {
const multipliers = generateMultipliers();
const results = {};
try {
const response = await fetch('https://jsonplaceholder.typicode.com/users');
const data = await response.json();
for (const multiplier of multipliers) {
const sampleArray = Array.from({
length: multiplier
}, () => data).flat();
// console.log(`Array Length for multiplier ${multiplier}: ${sampleArray.length}`);
results[multiplier] = {
reduce: benchmarkReduce(sampleArray),
fromEntries: benchmarkFromEntries(sampleArray),
forEach: benchmarkForEach(sampleArray),
forLoop: benchmarkLoop(sampleArray),
objectAssign: benchmarkObjectAssign(sampleArray),
spreadOperator: benchmarkSpreadOperator(sampleArray),
};
}
storeResults(results);
} catch (err) {
console.error(err);
}
}
executeBenchmarks();
import json
import matplotlib.pyplot as plt
# Load the JSON data
with open('/PATH/TO/results.json') as f:
data = json.load(f)
# Initialize lists for x values and a dictionary for y values
x_values = []
y_values = {
"reduce": [],
"fromEntries": [],
"forEach": [],
"forLoop": [],
"objectAssign": [],
"spreadOperator": []
}
# Fill the lists with data
for key in sorted(data.keys(), key=int):
x_values.append(int(key))
for func in y_values.keys():
y_values[func].append(float(data[key][func])) # Convert the values to float
# Create the plot
plt.figure(figsize=(10, 6))
# Plot each function with distinct, differentiable colors and thinner lines
colors = {
"reduce": "blue",
"fromEntries": "green",
"forEach": "orange",
"forLoop": "red",
"objectAssign": "purple",
"spreadOperator": "brown"
}
for func, color in colors.items():
plt.plot(x_values, y_values[func], label=func, color=color, linewidth=1.5, marker='o', markersize=4)
# Customize the plot
plt.title("Function Performance over Time")
plt.xlabel("Number of Objects")
plt.ylabel("Time (ms)")
plt.legend(loc="upper left")
plt.grid(True)
plt.tight_layout()
# Show the plot
plt.show()
_.keyBy(formerly_.indexBy): lodash.com/docs#keyBy_.toPlainObject. Ex:var myObj = _.toPlainObject(myArr)