113

I have two arrays: newParamArr and paramVal.

Example values in the newParamArr array: [ "Name", "Age", "Email" ].

Example values in the paramVal array: [ "Jon", 15, "[email protected]" ].

I need to create a JavaScript object that places all of the items in the array in the same object. For example { [newParamArr[0]]: paramVal[0], [newParamArr[1]]: paramVal[1], ... }.

In this case, the result should be { Name: "Jon", "Age": 15, "Email": "[email protected]" }.

The lengths of the two arrays are always the same, but the length of arrays can increase or decrease. That means newParamArr.length === paramVal.length will always hold.

None of the below posts could help to answer my question:

Javascript Recursion for creating a JSON object

Recursively looping through an object to build a property list

Sebastian Simon
19.8k8 gold badges61 silver badges88 bronze badges
asked Aug 24, 2016 at 15:58
9
  • please add some data of newParamArr and paramVal and the wanted result. Commented Aug 24, 2016 at 16:00
  • @NinaScholz Examples added Commented Aug 24, 2016 at 16:04
  • 1
    What does this have to do with recursion? Commented Aug 24, 2016 at 16:07
  • @FelixKling Was just doing some research and that term popped up, made it seem like it was hard to do without it. Commented Aug 24, 2016 at 16:09
  • is the value of newParamArr[i]an array with the content ["Name", "Age", "Email"]or is the array newParamArr = ["Name", "Age", "Email"]? Commented Aug 24, 2016 at 16:12

10 Answers 10

197

var keys = ['foo', 'bar', 'baz'];
var values = [11, 22, 33]
var result = {};
keys.forEach((key, i) => result[key] = values[i]);
console.log(result);

Alternatively, you can use Object.assign

result = Object.assign(...keys.map((k, i) => ({[k]: values[i]})))

or the object spread syntax (ES2018):

result = keys.reduce((o, k, i) => ({...o, [k]: values[i]}), {})

or Object.fromEntries (ES2019):

Object.fromEntries(keys.map((_, i) => [keys[i], values[i]]))

In case you're using lodash, there's _.zipObject exactly for this type of thing.

Sign up to request clarification or add additional context in comments.

5 Comments

Yes that is the result I wanted, let me test it!
Probably the short and simple answer ever. Working like a charm!
The "ES2018" example is just a fancy antipattern! Spreading Objects internally, on every N iteration is way too expensive - when just a simple assignment is all it takes.
Currently if you use this method on two arrays where keys are not unique (ie 'foo' appears multiple time in the keys array), you end up with a reduced object where the value for each key is just the last matched value. And earlier values are lost. (It's very frustrating!) How can this approach be amended so that the values are accumulated into an array of all matching values for each key, or perhaps instead a sum of all matching values? I wanted to use _.groupBy from lodash to create these groups but that only seems to group by value, not by key.
Using forEach seems to be quite speedy as well: jsperf.app/sezabi.
10

Using ECMAScript2015:

const obj = newParamArr.reduce((obj, value, index) => {
 obj[value] = paramArr[index];
 return obj;
}, {});

(EDIT) Previously misunderstood the OP to want an array:

const arr = newParamArr.map((value, index) => ({[value]: paramArr[index]}))
answered Aug 24, 2016 at 16:04

2 Comments

This will return an array of single-key objects; it will not combine everything into one object. You'd want reduce instead.
@craigmichaelmartin While your original answer did not satisfy OP's requirements, it however was exactly what I was looking for. ie. Mapping values from two arrays and combining them into individual objects dynamically. Thankyou!
8

I needed this in a few places so I made this function...

function zip(arr1,arr2,out={}){
 arr1.map( (val,idx)=>{ out[val] = arr2[idx]; } );
 return out;
}
console.log( zip( ["a","b","c"], [1,2,3] ) );
> {'a': 1, 'b': 2, 'c': 3} 
answered Aug 8, 2019 at 13:00

Comments

5

I know that the question is already a year old, but here is a one-line solution:

Object.assign( ...newParamArr.map( (v, i) => ( {[v]: paramVal[i]} ) ) );
answered Oct 31, 2017 at 13:00

2 Comments

It's 1 line, but it creates an unnecessary intermediate array
@bernie and lots of unnecessary objects
4

The following worked for me.

//test arrays
var newParamArr = [1, 2, 3, 4, 5];
var paramVal = ["one", "two", "three", "four", "five"];
//create an empty object to ensure it's the right type.
var obj = {};
//loop through the arrays using the first one's length since they're the same length
for(var i = 0; i < newParamArr.length; i++)
{
 //set the keys and values
 //avoid dot notation for the key in this case
 //use square brackets to set the key to the value of the array element
 obj[newParamArr[i]] = paramVal[i];
}
console.log(obj);
answered Aug 24, 2016 at 17:25

1 Comment

i did the same now looking at this, This is best way to see exactly what is happening with loop elements.
2

You can use Object.assign.apply() to merge an array of {key:value} pairs into the object you want to create:

Object.assign.apply({}, keys.map( (v, i) => ( {[v]: values[i]} ) ) )

A runnable snippet:

var keys = ['foo', 'bar', 'baz'];
var values = [11, 22, 33]
var result = Object.assign.apply({}, keys.map( (v, i) => ( {[v]: values[i]} ) ) );
console.log(result); //returns {"foo": 11, "bar": 22, "baz": 33}

See the documentation for more

answered May 9, 2018 at 17:07

Comments

1

This one works for me.

 var keys = ['foo', 'bar', 'baz'];
 var values = [11, 22, 33]
 var result = {};
 keys.forEach(function(key, i){result[key] = values[i]});
 console.log(result);

answered Aug 2, 2020 at 17:21

Comments

1

Object.fromEntries takes an array of key, value tuples and return the zipped result as object, you can then use it as follow:

 const keys = ["a","b","c"];
 const values = [1,2,3];
 Object.fromEntries(keys.map((key, index)=> [key, values[index]])); // {a: 1, b: 2, c: 3}
 
answered Mar 2, 2021 at 10:09

Comments

0

Use a loop:

var result = {};
for (var i = 0; i < newParamArr.length; i++) {
 result[newParamArr[i]] = paramArr[i];
}
answered Aug 24, 2016 at 16:04

Comments

0

A function using Array.reduce

const keys = ['foo', 'bar', 'baz'];
const values = [11, 22, 33];
console.log(combine2Object({keys, values}));
console.log(combine2Object());
function combine2Object( {keys = [`empty`], values = [true]} = {} ) {
 return keys.reduce( (acc, v, i) => ({...acc, [v]: values[i]}), {});
}

But, but, but, my teacher says I can't use loops!

Ok.

const keys = ['foo', 'bar', 'baz'];
const values = [11, 22, 33];
const obj = {};
obj[keys[0]] = values[0];
obj[keys[1]] = values[1];
obj[keys[2]] = values[2];
console.log(obj);
// or if you want to impress your teacher
// even more
const wowzer = {
 [keys[0]]: values[0],
 [keys[1]]: values[1],
 [keys[2]]: values[2],
};
console.log(`Wowzer! `, wowzer);

Now ask your teacher what to do when you can't use loops and the length of keys-/values arrays is not known up front.

answered Jun 20, 2024 at 13:34

Comments

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.