admin管理员组

文章数量:1134248

I have:

var keys = [ "height", "width" ];
var values = [ "12px", "24px" ];

And I'd like to convert it into this object:

{ height: "12px", width: "24px" }

In Python, there's the simple idiom dict(zip(keys,values)). Is there something similar in jQuery or plain JavaScript, or do I have to do this the long way?

I have:

var keys = [ "height", "width" ];
var values = [ "12px", "24px" ];

And I'd like to convert it into this object:

{ height: "12px", width: "24px" }

In Python, there's the simple idiom dict(zip(keys,values)). Is there something similar in jQuery or plain JavaScript, or do I have to do this the long way?

Share Improve this question edited May 15, 2020 at 3:13 Penny Liu 17.3k5 gold badges86 silver badges108 bronze badges asked Jul 13, 2009 at 6:18 itsadokitsadok 29.3k31 gold badges132 silver badges174 bronze badges 1
  • The same question with underscore.js: merge two arrays of keys and values to an object using underscore. – Sebastian Simon Commented Sep 7, 2021 at 9:32
Add a comment  | 

14 Answers 14

Reset to default 44

The simplest ES6 one-liner solution using Array reduce:

const keys = ['height', 'width'];
const values = ['12px', '24px'];
const merged = keys.reduce((obj, key, index) => ({ ...obj, [key]: values[index] }), {});

console.log(merged);

Simple JS function would be:

function toObject(names, values) {
    var result = {};
    for (var i = 0; i < names.length; i++)
         result[names[i]] = values[i];
    return result;
}

Of course you could also actually implement functions like zip, etc as JS supports higher order types which make these functional-language-isms easy :D

use lodash.

_.zipObject

Example

_.zipObject(['a', 'b'], [1, 2]);
// ➜ { 'a': 1, 'b': 2 }

As an alternate solution, not already mentioned I think :

const keys = ["height", "width"];
const values = ["12px", "24px"];
const result = {};

keys.forEach((key, idx) => result[key] = values[idx]);
console.log(result);

You can combine two arrays with map method, then convert it with Object.fromEntries.

var keys = ["height", "width"];
var values = ["12px", "24px"];

var array = keys.map((el, i) => {
  return [keys[i], values[i]];
});
// → [["height", "12px"], ["width", "24px"]]

var output = Object.fromEntries(array);
// → {height: "12px", width: "24px"}
console.log(output);

A functional approach with immutability in mind:

const zipObj = xs => ys => xs.reduce( (obj, x, i) => ({ ...obj, [x]: ys[i] }), {})

const arr1 = ['a', 'b', 'c', 'd']
const arr2 = ['e', 'f', 'g', 'h']

const obj = zipObj (arr1) (arr2) 

console.log (obj)

You could use a reduce() function to map the key-value pairs to an object.

/**
 *  Apply to an existing or new object, parallel arrays of key-value pairs.
 *
 *  @param   {string[]} keys      - List of keys corresponding to their accociated values.
 *  @param   {object[]} vals      - List of values corresponding to their accociated keys.
 *  @param   {object}   [ref={}]  - Optional reference to an existing object to apply to.
 *
 *  @returns {object} - The modified or new object with the new key-value pairs applied.
 */
function toObject(keys, vals, ref) {
  return keys.length === vals.length ? keys.reduce(function(obj, key, index) {
    obj[key] = vals[index];
    return obj;
  }, ref || {}) : null;
}

var keys   = [ "height" , "width" ];
var values = [ "12px"   , "24px"  ];

document.body.innerHTML = '<pre>' + JSON.stringify(toObject(keys, values), null, 2) + '</pre>';

Now we have Object.fromEntries we can do something like that:

const keys = [ "height", "width" ];
const values = [ "12px", "24px" ];
const myObject = Object.fromEntries(
    values.map((value, index) => [keys[index], value])
);

console.log(myObject);

Here's an example with all consts (non-modifying) and no libraries.

const keys = ["Adam", "Betty", "Charles"];
const values = [50, 1, 90];
const obj = keys.reduce((acc, key, i) => {
  acc[key] = values[i];
  return acc;
}, {});
console.log(obj);

Alternatively, if you'd consider libraries you could use lodash zipobject which does just what you asked.

You could transpose the arrays and get the object with the entries.

const
    transpose = (r, a) => a.map((v, i) => [...(r[i] || []), v]),
    keys = [ "height", "width" ],
    values = [ "12px", "24px" ],
    result = Object.fromEntries([keys, values].reduce(transpose, []));

console.log(result);

function combineObject( keys, values)
{
    var obj = {};
    if ( keys.length != values.length)
       return null;
    for (var index in keys)
        obj[keys[index]] = values[index];
     return obj;
};


var your_obj = combine( your_keys, your_values);

Here's one which will transform nested arrays into an array of multiple key-value objects.

var keys = [
  ['#000000', '#FFFFFF'],
  ['#FFFF00', '#00FF00', '#00FFFF', '#0000FF'],
];
var values = [
  ['Black', 'White'],
  ['Yellow', 'Green', 'Cyan', 'Blue'],
];
const zipObj = xs => ys => xs.reduce( (obj, x, i) => ({ ...obj, [x]: ys[i] }), {})
var array = keys.map((el, i) => zipObj (keys[i]) (values[i]));

console.log(array);

Output is

[
  {
    "#000000": "Black",
    "#FFFFFF": "White"
  },
  {
    "#FFFF00": "Yellow",
    "#00FF00": "Green",
    "#00FFFF": "Cyan",
    "#0000FF": "Blue"
  }
]

Providing a solution with a for...of loop.

var keys = ["height", "width"];
var values = ["12px", "24px"];
const result = {};
for (let [index, key] of keys.entries())
  result[key] = values[index];
console.log(result);
You can also use a library like ramda which has zipObj function. Example:

const keys = ["height", "width"];
const values = ["12px", "24px"];
const result = R.zipObj(keys, values);
console.log(result);

In the jQuery-Utils project, the ArrayUtils module has a zip function implemented.

//...
zip: function(object, object2, iterator) {
    var output = [];
    var iterator = iterator || dummy;
        $.each(object, function(idx, i){
        if (object2[idx]) { output.push([i, object2[idx]]); }
    });
    return output;
}
//...

本文标签: jsonMerge keys array and values array into an object in JavaScriptStack Overflow