在JavaScript中将键数组和值数组合并为一个对象

59

我有:

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

我想把它转换成这个对象:

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

在Python中,有一个简单的习语dict(zip(keys,values))。在jQuery或纯JavaScript中是否有类似的东西,还是我必须走一条漫长的路?

使用underscore.js的同一个问题:如何使用underscore将两个键值数组合并为一个对象 - Sebastian Simon
14个回答

44

使用数组reduce的最简单的ES6一行代码解决方案:

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

console.log(merged);


正确的现代版本 - user670839

32

简单的JS函数如下:

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

当然,你还可以实际上用JS支持的高阶类型来实现像zip等函数,这些功能式语言主义也很容易 :D


1
如果名称具有相同的键,则该函数将失败。 - user1927627
@user1927627 不会,它只会使用最后一次出现的内容,正如人们所期望的那样。 - OscarJ
帮忙为多个数组值设置标题。将其作为对象请求。value[0].width;var header = ["height", "width"]; var values = []; values[0] = ["12px", "24px"]; values[1] = ["14px", "33px"]; /或者/ var header = ["height", "width"]; var values = [["12px", "24px"], ["14px", "33px"]];有什么想法吗? - user3768564

26

使用lodash。

_.zipObject

示例

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

这应该是被接受的答案。自己编写(就像其他所有答案一样)是浪费时间。Underscore 中此函数的原始名称(您还会在旧版本的 Lodash 中找到)是 _.object - Julian
为了这个而包含整个库吗?自己编写代码不会拉入大量未使用的代码。 - live627

19
作为一种尚未提到的替代方案,我认为:

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

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


13
你可以使用map方法将两个数组合并,然后使用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);


7

以不可变性为中心的功能性方法:

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)


你能给我指一些关于zipObj(arr1, arr2)和zipObj(arr1)(arr2)详细区别的文档吗? - Jeferson Euclides
1
@JefersonEuclides 嘿,第二个被称为柯里化和部分应用。 - Matías Fidemraizer

4
您可以使用`reduce()`函数将键值对映射为对象。

/**
 *  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>';


4
现在我们有了Object.fromEntries,我们就可以像这样做:

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

console.log(myObject);


3
以下是所有常量(非修改)且不涉及任何库的示例。

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

或者,如果您考虑使用库,可以使用lodash zipobject,它可以完成您所需的操作。


2

您可以转置数组并获取具有条目的对象。

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


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接