从键数组和值数组创建对象

Posted

技术标签:

【中文标题】从键数组和值数组创建对象【英文标题】:Create an object from an array of keys and an array of values 【发布时间】:2016-12-31 20:45:52 【问题描述】:

我有两个数组:newParamArrparamVal

newParamArr 数组中的示例值:[ "Name", "Age", "Email" ]

paramVal 数组中的示例值:[ "Jon", 15, "jon@gmail.com" ]

我需要创建一个 javascript 对象,将数组中的所有项目放在同一个对象中。例如 [newParamArr[0]]: paramVal[0], [newParamArr[1]]: paramVal[1], ...

在这种情况下,结果应该是 Name: "Jon", "Age": 15, "Email": "jon@gmail.com"

两个数组的长度总是相同的,但是数组的长度可以增加也可以减少。这意味着newParamArr.length === paramVal.length 将始终保持不变。

以下帖子都无法回答我的问题:

Javascript Recursion for creating a JSON object

Recursively looping through an object to build a property list

【问题讨论】:

请添加newParamArrparamVal的一些数据和想要的结果。 @NinaScholz 添加示例 这和递归有什么关系? @FelixKling 只是在做一些研究,突然出现了这个词,看起来好像没有它很难做到。 newParamArr[i]一个数组的值["Name", "Age", "Email"]或者是数组newParamArr = ["Name", "Age", "Email"] 【参考方案1】:

使用 ECMAScript2015:

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

(编辑)以前误解了 OP 想要一个数组:

const arr = newParamArr.map((value, index) => ([value]: paramArr[index]))

【讨论】:

这将返回一个单键对象数组;它不会将所有东西组合成一个对象。你会想要reduce @craigmichaelmartin 虽然您的原始答案不满足 OP 的要求,但它正是我想要的。 IE。映射来自两个数组的值并将它们动态组合成单个对象。谢谢!【参考方案2】:

使用循环:

var result = ;
for (var i = 0; i < newParamArr.length; i++) 
  result[newParamArr[i]] = paramArr[i];

【讨论】:

也测试这个【参考方案3】:

var keys = ['foo', 'bar', 'baz'];
var values = [11, 22, 33]

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

或者,您可以使用Object.assign

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

或对象扩展语法(ES2018):

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

Object.fromEntries(ES2019):

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

如果您使用的是 lodash,那么 _.zipObject 正是针对这种类型的东西。

【讨论】:

是的,这就是我想要的结果,让我测试一下! 可能是最简单的答案。像魅力一样工作! “ES2018”示例只是一个花哨的反模式!在内部传播对象,每次 N 次迭代都太昂贵了 - 当只需要一个简单的分配时。 目前,如果您在两个键不唯一的数组上使用此方法(即“foo”在键数组中多次出现),您最终会得到一个简化的对象,其中每个键的值是只是最后一个匹配的值。并且早期的值丢失了。 (这非常令人沮丧!)如何修改这种方法,以便将值累积到每个键的所有匹配值的数组中,或者可能是所有匹配值的总和?我想使用 lodash 中的 _.groupBy 来创建这些组,但这似乎只是按值分组,而不是按键。【参考方案4】:

以下内容对我有用。

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

【讨论】:

我现在也做了同样的事情,这是了解循环元素到底发生了什么的最佳方式。【参考方案5】:

我知道这个问题已经有一年了,但这里有一个单行解决方案:

Object.assign( ...newParamArr.map( (v, i) => ( [v]: paramVal[i] ) ) );

【讨论】:

【参考方案6】:

您可以使用Object.assign.apply() 将一组 key:value 对合并到您要创建的对象中:

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

一个可运行的 sn-p:

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

更多信息请查看documentation

【讨论】:

【参考方案7】:

我在一些地方需要这个,所以我做了这个功能......

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 

【讨论】:

【参考方案8】:

这个对我有用。

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

【讨论】:

【参考方案9】:

Object.fromEntries 接受一个键值元组数组并将压缩结果作为对象返回:

Object.fromEntries(keys.map((key, index)=> [key, values[index]]))

【讨论】:

以上是关于从键数组和值数组创建对象的主要内容,如果未能解决你的问题,请参考以下文章

如何使用键和值创建json对象,其中value是数组

使用 Lodash 从键值对数组中创建对象

jQuery创建具有选定属性和值的对象

对象和数组

将对象数组转换为包含键和值的对象作为对象数组

根据来自不同对象数组的属性和值过滤对象数组