【问题标题】:Convert JS array into an object [duplicate]将JS数组转换为对象[重复]
【发布时间】:2016-05-22 17:08:07
【问题描述】:

我在这里找到了一些类似的主题,但不是真正适合我的问题的答案。使用 Javascript 我想将数组转换为对象。给定以下数组:

[{id:1,name:"aa"},{id:2,name:"bb"},{id:3,name:"cc"}]

我想达到这样的目标:

{1:{name:"aa"},2:{name:"bb"},3:{name:"cc"}}

最快/最短的方法是什么?考虑到我的数组中可能有 1000 个项目,我怎样才能以有效的方式实现此结果?

【问题讨论】:

标签: javascript arrays


【解决方案1】:

您可以使用Array.prototype.forEach() 遍历数组,以id 作为键并为该属性分配一个新对象。

var array = [{ id: 1, name: "aa" }, { id: 2, name: "bb" }, { id: 3, name: "cc" }],
    object = {};

array.forEach(function (a) {
    object[a.id] = { name: a.name };
});

document.write('<pre>' + JSON.stringify(object, 0, 4) + '</pre>');

【讨论】:

  • 使用 object[a.id] 而不是 object[i] 做我想要的。谢谢
  • 这是非常有效和简单的,但这不会考虑动态键,因为在你的'forEach'函数中你明确设置了'name'键。
  • @Brett84c,这不是规范。
【解决方案2】:

您可以选择将 1 更改为其他值。

var arrObject = [{id:1,name:"aa"},{id:2,name:"bb"},{id:3,name:"cc"}];

var jsObjectToJSONString = JSON.stringify({1: arrObject});

【讨论】:

  • 是的,这不是这个问题的预期答案,我想到了 JS 数组对象转换为 JSON 字符串。
【解决方案3】:

使用Array.prototype.reduce:

[{id:1,name:"aa"},{id:2,name:"bb"},{id:3,name:"cc"}].reduce(function(result, current) {
  result[current.id] = current;
  delete current.id;

  return result;
}, {});

我想没有循环就没有办法了吗?

正确。

循环处理包含 10000 个对象的数组不会“慢”吗?

定义“慢”。但是,是的,无论您对它们执行什么操作,10,000 个对象都很多。

编辑

您也可以使用_.keyBy 和(如果您喜欢实用程序库和函数式编程):

_.chain([{id:1,name:"aa"},{id:2,name:"bb"},{id:3,name:"cc"}])
.keyBy(function(o) {
  return o.id;
})
.mapValues(function(o) {
  return _.omit(o, ['id']);
})
.value();

【讨论】:

  • reduce 在这里没有提供任何实质内容,并且引入了复杂性(记住返回累加器,它实际上并没有改变)。这会引起错误,例如答案中的错误。 编辑: 编辑前的答案中的那个。 :-)
  • @T.J.Crowder 感谢您指出返回错误。但是,我认为在这种情况下,reduce 是 ES5 提供的原生迭代器中语义更丰富的选择之一。
  • 我的观点是reduce只有在累加器改变时才有用的语义选择,比如和。如果没有(它始终是同一个对象引用),我更喜欢简单地 forEach 关闭目标。各有各的。
  • @T.J.Crowder,公平点
  • 也有帮助,谢谢乔希。 “慢”当然..非常精确:)
【解决方案4】:

如果数组中的某些对象有可能具有不同的名称或存在的键数不同,我认为这是动态执行的方式,我认为这是理想的(请注意,我添加了一个“数字”字段到每个数组项)。

var objArr = [{id:1,name:"aa", number:25},{id:2,name:"bb", number:10},{id:3,name:"cc", number:8}],
    jsonObj = {};

for (var i = 0; i < objArr.length; i++) {
  jsonObj[i] = {};
  var keys = Object.keys(objArr[i]);
  //start at '1' to ignore 'id' key
  for (var j = 1; j < keys.length; j++) {
    jsonObj[i][keys[j]] = objArr[i][keys[j]];
  }
}

console.log(jsonObj);

【讨论】:

  • 这不会产生 OP 想要的输出。
  • 确实如此,但我想这不是“最快/最短的方式”。就个人而言,我认为像这样动态地执行它比在对象上静态设置“名称”属性更好。如果 JSON 在长度或不同的键名上发生任何变化,“最短/最快的方式”将不再适用。
  • 如果您查看预期的输出,您将看到该对象具有键 1、2、3,而您的具有 0、1、2。似乎 OP 想要使用对象的 id 作为属性名称,而不是它们在数组中的位置。
  • 啊,我明白了。我可以修改我的代码来解决这个问题,但在这一点上,这似乎并不重要。
猜你喜欢
  • 1970-01-01
  • 2017-08-11
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-11-04
  • 2019-07-14
  • 1970-01-01
相关资源
最近更新 更多