Create object from array

147,424

Solution 1

Simply

 const obj = {};

 for (const key of yourArray) {
      obj[key] = whatever;
 }

or if you prefer "functional" style:

 const obj = yourArray.reduce((o, key) => Object.assign(o, {[key]: whatever}), {});

using the modern object spread operator:

const obj = yourArray.reduce((o, key) => ({ ...o, [key]: whatever}), {})

Example:

[
  { id: 10, color: "red" },
  { id: 20, color: "blue" },
  { id: 30, color: "green" }
].reduce((acc, cur) => ({ ...acc, [cur.color]: cur.id }), {})

Output:

{red: 10, blue: 20, green: 30}

Here is how it works:

reduce is initialized with an empty object (empty {} at the end), therefore first iteration variables are acc = {} cur = { id: 10, color: "red" }. Function returns an object - this is why function body is wrapped in parentheses => ({ ... }). Spread operator doesn't do anything on the first iteration, so red: 10 is set as first item.

On the second iteration variables are acc = { red: 10 } cur = { id: 20, color: "blue" }. Here the spread operator expands acc and the function returns { red: 10, blue: 20 }.

Third iteration acc = { red: 10, blue: 20 } cur = { id: 30, color: "green" }, so when acc is spread inside the object, our function returns the final value.

Solution 2

The new Object.fromEntries, from ECMAScript 2019, makes it even easier to transform values from an array into keys in an object like follows

const dynamicArray = ["2007", "2008", "2009", "2010"];
const obj = Object.fromEntries(
  dynamicArray.map(year => [year, {
    something: "based",
    on: year
  }])
)

console.log(obj)

Or maybe to solve your own original problem

const width = 1920
const height = 1080
const dynamicArray = ["2007", "2008", "2009", "2010"];
const obj = Object.fromEntries(
  dynamicArray.map((year, i) => [year, {
    x: (( i + 1) / 5) * width,
    y: height / 2
  }])
)

console.log(obj)

Solution 3

in js with es6 reduce function for array I do it like this

let x = [1,2,3]
let y = x.reduce((acc, elem) => {
  acc[elem] = elem // or what ever object you want inside
  return acc
}, {})
console.log(y) // {1:1, 2:2, 3:3}

Solution 4

var keys = ['key1', 'key2', 'key3']

var object = Object.assign({}, ...Object.entries({...keys}).map(([a,b]) => ({ [b]: 'someValue' })))
console.log(object)

This will produce

{ key1: 'someValue', key2: 'someValue', key3: 'someValue' }

Solution 5

I found you can actually just use Object.assign() directly with the spread operator. No need to introduce any more complexity with a reduce or map function.

Simply do Object.assign(...yourArray, {}) and you will get your desired result. If you instead want to merge your array of objects into another object you can then also call Object.assign(...yourArray, yourObject) and it will also work just fine.

You can also use this same method to merge two arrays into one object, even if one of the arrays doesnt contain objects but only primitive values - however if you do this you need to make sure that at least one of the arrays hold only objects as a primitive will default to its index as the key, so you will get errors if there is a duplicate key.

However for OPs purpose there is no risk of such errors as he is merging with an empty object, which is the safest way.

const arr = [
  { a: 0 },
  { c: 1 },
  { e: 2 },
];

const obj = Object.assign({}, ...arr);

console.log(obj)

// Results to:
// Object { a: 0, c: 1, e: 2 }
Share:
147,424
Hussain Dehgamwala
Author by

Hussain Dehgamwala

Updated on September 14, 2021

Comments

  • Hussain Dehgamwala
    Hussain Dehgamwala over 2 years

    I want to create an object from a list inside an array. I have an array which is dynamic and supposed to look like this:

    var dynamicArray = ["2007", "2008", "2009", "2010"];

    And I want to make an object like this with some JavaScript ES6:

    const obj = {
        2007: {
            x: width / 5,
            y: height / 2
        },
        2008: {
            x: (2 / 5) * width,
            y: height / 2
        },
        2009: {
            x: (3 / 5) * width,
            y: height / 2
        },
        2010: {
            x: (4 / 5) * width,
            y: height / 2
        }
    }
    

    Don't worry about the inner objects. I just want to create a structure like this:

     obj = {
          2007: ...,
          2008: ...,
          ...
        }
    

    Please help, thanks.

  • Hussain Dehgamwala
    Hussain Dehgamwala about 7 years
    Thanks! It worked as required. I never knew about array.reduce function.
  • Aluan Haddad
    Aluan Haddad about 7 years
    If you prefer the functional style, and I do, you should use const. Actually you should use it regardless. Also, if you have access to ES Next rest/spread syntax (say via TypeScript or Babel) you can write const obj = yourArray.reduce((o, key) => ({ ...o, [key]: whatever}), {}) and even avoid mutating the seed :p
  • georg
    georg about 7 years
    @AluanHaddad: good suggestion, converted the post to CW, feel free to edit.
  • terary
    terary over 5 years
    ({ ...o, [key]: candidateDoc[key]}) .. where candidateDoc is some pojo. I want to take only values that are defined in candidateDoc. But I am confused with the parenthathese, can't seem to get a 'return' or an if statement to work. Could you point me into the right direction - not scared to read documentation.
  • cameck
    cameck over 4 years
    Concerning the "functional style" approaches, it seems to a bit overkill to copy the object on each iteration. I'd suggest adding onto the new object: yourArray.reduce((o, key) => { o[key] = whatever; return o; }, {}). Everything else looks great!
  • georg
    georg over 4 years
    @cameck: thanks, the post is CW, feel free to edit.
  • exebook
    exebook about 4 years
    even shorter: [1, 2, 3].reduce((x, y)=>(x[y] = 1, x), {})
  • Darshan theerth
    Darshan theerth about 3 years
    Good explanation for "reduce", Thank you so much
  • Tino
    Tino almost 3 years
    Edited as object.assign() needs the target object as the first parameter. Previously (object.assign(...arr, {})) the {} was a redundant, and the returned object was the first entry of the array arr. I don't think it was intended to change arr.
  • SagitSri
    SagitSri almost 3 years
    Thank you! you saved my day! Is the same thing can be done using the array unshift and splice?
  • Abderrahmane TAHRI JOUTI
    Abderrahmane TAHRI JOUTI almost 3 years
    The object assign solution even on the accepted answer is off topic, as op is starting from an array of strings and not an array of objects
  • Aasmund Berge Endresen
    Aasmund Berge Endresen almost 3 years
    I was just using it as an example of how it also can be used - but it works with an array of strings such as OP requested as well, as I mentioned it will then default the key to the index so it will be { 0: 'string1', 1: 'string2' }
  • Neel Dsouza
    Neel Dsouza almost 3 years
    @exebook Can u explain what is x doing inside the return function of reduce?
  • Admin
    Admin over 2 years
    As it’s currently written, your answer is unclear. Please edit to add additional details that will help others understand how this addresses the question asked. You can find more information on how to write good answers in the help center.
  • Monstar
    Monstar about 2 years
    What does "acc" stands for ?
  • Vasilis Tsirimokos
    Vasilis Tsirimokos about 2 years
    @Monstar it stands for the word "accumulator"