105

I have two arrays: newParamArr and paramVal.

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

Example values in the paramVal array: [ "Jon", 15, "jon@gmail.com" ].

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": "jon@gmail.com" }.

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
  • 18,263
  • 7
  • 55
  • 75
  • please add some data of `newParamArr` and `paramVal` and the wanted result. – Nina Scholz Aug 24 '16 at 16:00
  • @NinaScholz Examples added –  Aug 24 '16 at 16:04
  • 1
    What does this have to do with recursion? – Felix Kling Aug 24 '16 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. –  Aug 24 '16 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"]`? – Nina Scholz Aug 24 '16 at 16:12
  • Duplicate of [Create object from two arrays](http://stackoverflow.com/q/25037551/218196) – Felix Kling Aug 24 '16 at 16:13
  • @NinaScholz second option –  Aug 24 '16 at 16:21
  • Does this answer your question? [Create object from two arrays](https://stackoverflow.com/questions/25037551/create-object-from-two-arrays) – golopot Jan 14 '20 at 07:24
  • Does this answer your question? [Merge keys array and values array into an object in JavaScript](https://stackoverflow.com/questions/1117916/merge-keys-array-and-values-array-into-an-object-in-javascript) – shmuels May 26 '22 at 19:10

9 Answers9

192

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.

georg
  • 211,518
  • 52
  • 313
  • 390
  • Yes that is the result I wanted, let me test it! –  Aug 24 '16 at 16:06
  • 2
    Probably the short and simple answer ever. Working like a charm! – abhishake Aug 30 '19 at 11:27
  • 3
    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. – Roko C. Buljan Apr 19 '20 at 15:24
  • 1
    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. – Francis Barton Dec 03 '21 at 11:01
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]}))
craigmichaelmartin
  • 6,091
  • 1
  • 21
  • 25
  • This will return an array of single-key objects; it will not combine everything into one object. You'd want `reduce` instead. – Jacob Aug 24 '16 at 16:05
  • 1
    @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! – SeaWarrior404 Jul 03 '18 at 10:54
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} 
Roger Heathcote
  • 3,091
  • 1
  • 33
  • 39
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]} ) ) );
Space Games
  • 59
  • 1
  • 2
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);
Chris Rollins
  • 550
  • 3
  • 9
  • i did the same now looking at this, This is best way to see exactly what is happening with loop elements. – MFarooqi Sep 26 '19 at 10:12
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

LeCodex
  • 1,636
  • 14
  • 20
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}
    
Flavien Volken
  • 19,196
  • 12
  • 100
  • 133
0

Use a loop:

var result = {};
for (var i = 0; i < newParamArr.length; i++) {
  result[newParamArr[i]] = paramArr[i];
}
Jacob
  • 77,566
  • 24
  • 149
  • 228
0

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);
Ninja
  • 433
  • 3
  • 10