873

What is the best way to convert:

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

to:

{
  0: 'a',
  1: 'b',
  2: 'c'
}
3
  • 3
    If anyone else is looking for a Lodash solution, consider _.keyBy (formerly _.indexBy): lodash.com/docs#keyBy Commented Feb 18, 2016 at 2:26
  • 1
    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. Commented Apr 3, 2016 at 17:25
  • 3
    A simple way to do this with Lodash is _.toPlainObject. Ex: var myObj = _.toPlainObject(myArr) Commented Nov 4, 2016 at 19:36

47 Answers 47

1060

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" }
Sign up to request clarification or add additional context in comments.

10 Comments

Just want to point out - if you already have an array of sorted properties from the original object, using the spread operator is what will turn that array directly into a new object: { ...[sortedArray]}
Oriol, is there a way to set a fixed key instead of 0 & 1?
This is usually not what you want. Usually you want to use a property in the array element as a key. Thus, the reduce is what you want.
what if i want the key not as 0,1,2 but the same as the value? like: {a: 'a'} How do we do that ?
@Gel Use reduce like: arr.reduce((a, v) => ({ ...a, [v]: v}), {})
|
566

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.

16 Comments

@m93a it already is an object. In JavaScript, there's really no point creating an Array instance ([]) if you're not going to use numeric property keys and the "length" property.
cleaner way to avoid param reassign const obj = arr.reduce((obj, cur, i) => { return { ...obj, [i]: cur }; }, {});
Arrow + destructuring syntax w/o explicit return: const obj = arr.reduce((obj, cur, i) => ({ ...obj, [i]: cur }), {});
@eugene_sunic indeed, but that approach was not available when I answered this in 2010 :)
As @miro points out, creating a new object every time is not necessary, and in fact much slower than manipulating the initial object that was created. Running a JSPerf test on an array of 1000 elements, creating a new object every time is 1,000 times slower than mutating the existing object. jsperf.com/…
|
365

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.

1 Comment

Helpful with maintaining a redux store when you are using a map of objects and you need to drop one of the keys
106

If you're using jquery:

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

3 Comments

Weird, if I give in an Array variable it puts every character in a separate object: 0: "a", 1: ",", 2: "b"... So it ignores the quotes, but includes the commas...
@Max I think there is no such behavior. The returned object is {0: 'a', 1: 'b', 2: 'c'} what is an expected result.
Is there a way to use $.extend while also informing the keys in a non-numerical manner, ie: making calcultations on the array items?
81

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: '',
  // ...
}
*/

1 Comment

Thanks! I didn't konw about 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])
79

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

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

3 Comments

Actually this isn't natively available in ES2015 either. It is very elegant however.
how to get result - { "a": "a", "b":"b", "c":"c" } using spread?
60

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}), {})

1 Comment

I am wondering how fast this reduce thing is. In each iteration the object is cloned again and again with spread operator?
48

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

8 Comments

you downvote my response, but no comment? My answer is correct and tested. What is the objection?
This question has no underscore tag, and you are also assuming node.js or a require library.
underscore is pretty common on both client and server. It's assumed for Backbone.js and is probably THE most common utility library. That being said, I included the require line to make it clear I was using a library. There's no 1-liner for describing "add underscore.js to your page", so some translation is required for a browser environment
Still, if you’re using undserscore, a simple 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.
@CharlieMartin that analogy is completely flawed, because lodash, underscore, and jQuery are not "standard libraries" and, in a great number of JavaScript use cases, adding libraries directly impacts end users, which one should not do for trivial reasons.
|
31

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)

2 Comments

This is what I was looking for. I didn't need the indeces, I needed to transform the array into retained key-value pairs.
plus one for the KungFu, I need it for conversion of arr = [{ b: 1, d: 2 }] to obj.
28

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

5 Comments

(1) According to MDN, changing the [[Prototype]] of an object is a very slow operation. (2) This does not remove the own 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.
@Oriol mdn is wrong, at least in V8 (but also other engines) this is a pretty fast operation in this particular case - since objects have a numerical store anyway this is basically changing two pointers.
This also can be used for the fact that it is apparently unique among the other quick solutions, of preserving any non-index ("own") properties on the array (i.e., non-positive-integer properties)...
But hmm, Array.isArray is returning true for the "object" here even though instanceof Array does not...
@BrettZamir that sounds like a bug :D
19

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;

1 Comment

you can use arr.entries() instead of Object.entries(arr)
18

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

Comments

15

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

Comments

11

The shortest answer: (using destructuring)

const obj = { ...input }

Example:

const inputArray = ["a", "b", "c"]
const outputObj = { ...inputArray }

Comments

10

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

1 Comment

Not only are your variable names different, but your example will not work, creating a map from the constructor initially requires 2d key-value Array. new Map([['key1', 'value1'], ['key2', 'value2']]);
6

A quick and dirty one:

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

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

4 Comments

I think you forgot to test that; it produces {0:"c", 1:"b", 2:"a"}. You either want unshift instead of pop or (better) start with i=arr.length-1 and decrement instead.
yeah.. just changed it, but then it become less interesting :/
Could even do l = arr.length, and then while (l && (obj[--l] = arr.pop())){} (I realize this is old, but why not simplify it even further).
Is it faster then the other solutions?
6

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

Comments

6

Quick and dirty #2:

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

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

3 Comments

Why are you using comma notation?
Personal preference to have the comma leading on the next line. I find this notation easier to read.
The loop will stop if the array contains a falsy value. You should check i < a.length instead of a[i].
6

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?

2 Comments

Rather than just criticizing other answers for not trying something, you can explain what advantages your answer has or how it differs from the top answer using "spread syntax". Hint: See developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/….
how to make keys is value ?
5

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

7 Comments

This destroys both the keys array content and, despite the internal comment, also the values array (its contents). JavaScript works differently than PHP with JavaScript automatically acting by reference on the properties of an object/array.
No it doesn't, the routine makes copies, the original is not touched.
Yes, the original is touched. See jsfiddle.net/bRTv7 . The array lengths end up both being 0.
Ok, the edited version I just changed it with does not destroy the arrays, find that strange that it should have done that.
Updated method that should be supported in older browsers as JSON has been around longer than ECMA added new code features
|
4

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

1 Comment

This should be higher up, if you have ['a' = '1', 'b' = '2', 'c' = '3'] and want it like {a: 1, b: 2, c: 3} this works perfect.
4
.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]

1 Comment

What did you intend with [/docs]? It would be more useful to make the code snippets executable.
4

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>

Comments

4

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

1 Comment

Note you can do: Object.fromEntries(valueMap) to convert the map to an object
3

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.

Comments

3

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

Comments

3

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

1 Comment

What if I want to convert to { name: a, div :b, salary:c}
3

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

Comments

3

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:

  1. enforce first param to be array of objects
  2. help to select the key
  3. 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

Here's a demo.

4 Comments

This is nice and easily modified to meet other reqs
Excellent little solution, works like a charm! How to change the output into '123': 'aaa' as per your example?
Modified function for anyone looking to do what I needed: 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]: Object.entries(cur).reduce((str, [p, val]) => { return ${val}; }, '') }) }, {} as Record<K, T>);
Does not work with Date types. Try adding a new property of type Date, then select it
3

Well, it depends...

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.

Function performance over time

Summary

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.

Benchmarks

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

Plotting results

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

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.