将数组转换为对象

IT技术 javascript arrays node.js object
2021-01-29 02:16:42

什么是最好的转换方式:

['a','b','c']

到:

{
  0: 'a',
  1: 'b',
  2: 'c'
}
6个回答

ECMAScript 6 引入了易于填充的Object.assign

Object.assign()方法用于将所有可枚举的自身属性的值从一个或多个源对象复制到目标对象。它将返回目标对象。

Object.assign({}, ['a','b','c']); // {0:"a", 1:"b", 2:"c"}

length数组自己的属性不会被复制,因为它不可枚举。

此外,您可以在对象上使用 ES8扩展语法来实现相同的结果:

{ ...['a', 'b', 'c'] }

对于自定义键,您可以使用reduce

['a', 'b', 'c'].reduce((a, v) => ({ ...a, [v]: v}), {}) 
// { a: "a", b: "b", c: "c" }
只是想指出 - 如果您已经从原始对象中获得了一组已排序的属性,则使用扩展运算符可以将该数组直接转换为新对象:{ ...[sortedArray]}
2021-03-12 02:16:42
这通常不是您想要的。通常你想使用数组元素中的一个属性作为键。因此,减少就是你想要的。
2021-03-14 02:16:42
@Gel 使用reduce如下:arr.reduce((a, v) => ({ ...a, [v]: v}), {})
2021-03-29 02:16:42
Oriol,有没有办法设置固定键而不是 0 & 1?
2021-04-01 02:16:42
如果我想要键不是 0,1,2 而是与值相同怎么办?比如:{a: 'a'} 我们怎么做?
2021-04-04 02:16:42

使用这样的功能:

function toObject(arr) {
  var rv = {};
  for (var i = 0; i < arr.length; ++i)
    rv[i] = arr[i];
  return rv;
}

你的数组已经或多或少只是一个对象,但数组确实有一些关于整数命名属性的“有趣”和特殊行为。以上将为您提供一个简单的对象。

编辑哦,您可能还想考虑数组中的“漏洞”:

function toObject(arr) {
  var rv = {};
  for (var i = 0; i < arr.length; ++i)
    if (arr[i] !== undefined) rv[i] = arr[i];
  return rv;
}

在现代 JavaScript 运行时中,您可以使用以下.reduce()方法:

var obj = arr.reduce(function(acc, cur, i) {
  acc[i] = cur;
  return acc;
}, {});

那个也避免了阵列中的“漏洞”,因为这就是.reduce()工作原理。

避免参数重新分配的更干净的方法 const obj = arr.reduce((obj, cur, i) => { return { ...obj, [i]: cur }; }, {});
2021-03-18 02:16:42
没有显式返回的箭头 + 解构语法: const obj = arr.reduce((obj, cur, i) => ({ ...obj, [i]: cur }), {});
2021-03-19 02:16:42
@eugene_sunic 确实,但是当我在 2010 年回答这个问题时,这种方法不可用:)
2021-03-21 02:16:42
正如@VivekN 所说,每次都需要创建新对象吗?怎么样arr.reduce((obj, cur, i) => (obj[i]=cur,obj), {});
2021-03-23 02:16:42
@m93a 它已经是一个对象。在 JavaScript 中,[]如果您不打算使用数字属性键和“长度”属性,那么创建 Array 实例 ( )真的没有意义
2021-03-24 02:16:42

您可以使用累加器 aka reduce

['a','b','c'].reduce(function(result, item, index, array) {
  result[index] = item; //a, b, c
  return result;
}, {}) //watch out the empty {}, which is passed as "result"

传递一个空对象{}作为起点;然后逐步“增加”该对象。在迭代结束时,result{"0": "a", "1": "b", "2": "c"}

如果您的数组是一组键值对对象:

[{ a: 1},{ b: 2},{ c: 3}].reduce(function(result, item) {
  var key = Object.keys(item)[0]; //first property: a, b, c
  result[key] = item[key];
  return result;
}, {});

将产生: {a: 1, b: 2, c: 3}

为了完整起见,reduceRight允许您以相反的顺序遍历数组:

[{ a: 1},{ b: 2},{ c: 3}].reduceRight(/* same implementation as above */)

将产生: {c:3, b:2, a:1}

您的蓄能器可以是适合您特定目的的任何类型。例如,为了在数组中交换对象的键和值,请传递[]

[{ a: 1},{ b: 2},{ c: 3}].reduce(function(result, item, index) {
  var key = Object.keys(item)[0]; //first property: a, b, c
  var value = item[key];
  var obj = {};
  obj[value] = key;
  result.push(obj);
  return result;
}, []); //an empty array

将产生: [{1: "a"}, {2: "b"}, {3: "c"}]

与 不同mapreduce不能用作 1-1 映射。您可以完全控制要包含或排除的项目。因此reduce可以让你实现什么filter功能,这使得它reduce非常通用:

[{ a: 1},{ b: 2},{ c: 3}].reduce(function(result, item, index) {
  if(index !== 0) { //skip the first item
    result.push(item);
  }
  return result;
}, []); //an empty array

将产生: [{2: "b"}, {3: "c"}]

注意reduceObject.keyECMA 5th edition; 您应该为不支持它们的浏览器(特别是 IE8)提供一个 polyfill。

查看Mozilla的默认实现

当您使用对象映射并且需要删除其中一个键时,有助于维护 redux 存储
2021-03-29 02:16:42

如果您使用的是 jquery:

$.extend({}, ['a', 'b', 'c']);
有没有办法在使用 $.extend 的同时以非数字方式通知键,即:对数组项进行计算?
2021-03-10 02:16:42
超级棒和简短的测试
2021-03-11 02:16:42
奇怪的是,如果我输入一个 Array 变量,它会将每个字符放在一个单独的对象中:0: "a", 1: ",", 2: "b" ... 所以它忽略引号,但包括逗号.. .
2021-04-06 02:16:42
@Max 我认为没有这种行为。返回的对象是{0: 'a', 1: 'b', 2: 'c'}预期的结果。
2021-04-07 02:16:42

为了完整起见,ECMAScript 2015(ES6) 正在传播。将需要转译器(Babel)或至少运行 ES6 的环境。

console.log(
   { ...['a', 'b', 'c'] }
)

如何获得结果 - { "a": "a", "b":"b", "c":"c" } 使用传播?
2021-03-14 02:16:42
实际上,这在 ES2015 中也不是原生可用的。然而,它非常优雅。
2021-03-18 02:16:42
2021-03-22 02:16:42