【问题标题】:How to convert an array of key-value tuples into an object如何将键值元组数组转换为对象
【发布时间】:2015-11-07 05:51:45
【问题描述】:

我有一个数组:

[ [ 'cardType', 'iDEBIT' ],
  [ 'txnAmount', '17.64' ],
  [ 'txnId', '20181' ],
  [ 'txnType', 'Purchase' ],
  [ 'txnDate', '2015/08/13 21:50:04' ],
  [ 'respCode', '0' ],
  [ 'isoCode', '0' ],
  [ 'authCode', '' ],
  [ 'acquirerInvoice', '0' ],
  [ 'message', '' ],
  [ 'isComplete', 'true' ],
  [ 'isTimeout', 'false' ] ]

但我无法通过数组的键访问数据,例如arr['txnId'] 不返回 20181。如何将上面的元组数组转换成一个对象,这样我就可以很方便的按键访问数据了。

【问题讨论】:

标签: javascript arrays


【解决方案1】:

2020 年更新: 在所有现代浏览器上,baao notesObject.fromEntries(arr) 现在是 does this


您可以使用Object.assignspread operatordestructuring assignment 作为使用map 而不是@royhowie’s reduce 的方法,这可能更直观,也可能不直观:

Object.assign(...arr.map(([key, val]) => ({[key]: val})))

例如:

var arr = [ [ 'cardType', 'iDEBIT' ],
  [ 'txnAmount', '17.64' ],
  [ 'txnId', '20181' ],
  [ 'txnType', 'Purchase' ],
  [ 'txnDate', '2015/08/13 21:50:04' ],
  [ 'respCode', '0' ],
  [ 'isoCode', '0' ],
  [ 'authCode', '' ],
  [ 'acquirerInvoice', '0' ],
  [ 'message', '' ],
  [ 'isComplete', 'true' ],
  [ 'isTimeout', 'false' ] ]

var obj = Object.assign(...arr.map(([key, val]) => ({[key]: val})))

console.log(obj)

【讨论】:

  • Computed property names 也用于{[d[0]]: d[1]} :)
  • Object.assign.apply(null, arr.map(([key, val]) => { return { [key]: val } })) 更容易阅读和理解(当分成多行时)。
  • 点是什么...?
  • 一种类似的单线(带reduce),具有更可链接的优点:arr.reduce((obj, d) => Object.assign(obj, {[d[0]]: d[1]}), {})
  • Object.assign(...array.map( ([key, val]) => ({ [key]: val }) )) — @Toph 的回答和 @royhowie 的评论的整合。
【解决方案2】:

2020 年 6 月更新

ECMAScript 2021 带来了 Object.fromEntries,它完全符合要求:

const array =    [ [ 'cardType', 'iDEBIT' ],
      [ 'txnAmount', '17.64' ],
      [ 'txnId', '20181' ],
      [ 'txnType', 'Purchase' ],
      [ 'txnDate', '2015/08/13 21:50:04' ],
      [ 'respCode', '0' ],
      [ 'isoCode', '0' ],
      [ 'authCode', '' ],
      [ 'acquirerInvoice', '0' ],
      [ 'message', '' ],
      [ 'isComplete', 'true' ],
      [ 'isTimeout', 'false' ] ];
      
const obj = Object.fromEntries(array);
console.log(obj);

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/fromEntries

这样就可以了:

const array =    [ [ 'cardType', 'iDEBIT' ],
      [ 'txnAmount', '17.64' ],
      [ 'txnId', '20181' ],
      [ 'txnType', 'Purchase' ],
      [ 'txnDate', '2015/08/13 21:50:04' ],
      [ 'respCode', '0' ],
      [ 'isoCode', '0' ],
      [ 'authCode', '' ],
      [ 'acquirerInvoice', '0' ],
      [ 'message', '' ],
      [ 'isComplete', 'true' ],
      [ 'isTimeout', 'false' ] ];
    
var obj = {};
array.forEach(function(data){
    obj[data[0]] = data[1]
});
console.log(obj);

【讨论】:

  • 看起来下面的新 Map(array) 解决方案更简单
  • 甚至用“reduce”方法回答
【解决方案3】:

更惯用的方法是使用Array.prototype.reduce

var arr = [
  [ 'cardType', 'iDEBIT' ],
  [ 'txnAmount', '17.64' ],
  [ 'txnId', '20181' ],
  [ 'txnType', 'Purchase' ],
  [ 'txnDate', '2015/08/13 21:50:04' ],
  [ 'respCode', '0' ],
  [ 'isoCode', '0' ],
  [ 'authCode', '' ],
  [ 'acquirerInvoice', '0' ],
  [ 'message', '' ],
  [ 'isComplete', 'true' ],
  [ 'isTimeout', 'false' ]
];

var obj = arr.reduce(function (o, currentArray) {
  var key = currentArray[0], value = currentArray[1]
  o[key] = value
  return o
}, {})

console.log(obj)
document.write(JSON.stringify(obj).split(',').join(',<br>'))

这在使用 ES6 (rest parameters) 语法时更具视觉吸引力:

let obj = arr.reduce((o, [ key, value ]) => {
    o[key] = value
    return o
}, {})

【讨论】:

  • 更简洁的方法来避免参数重新分配const obj = arr.reduce((obj, [ key, value ]) =&gt; { return { ...obj, [key]: value }; }, {});
  • 甚至避免return语句:const obj = arr.reduce(obj, [key, value] =&gt; ({ ...obj, [key]: value }), {})
【解决方案4】:

使用Map

new Map(array);

Map 对象保存键值对并记住原来的 键的插入顺序。任何值(对象和基元) values) 可以用作键或值。

这是有效的,因为您的变量 array 的类型是 Array&lt;[key,value]&gt;Map 构造函数可以使用数组数组进行初始化,其中内部数组的第一个元素是键,第二个元素是值。

const array = [
  ['cardType', 'iDEBIT'],
  ['txnAmount', '17.64'],
  ['txnId', '20181'],
  ['txnType', 'Purchase'],
  ['txnDate', '2015/08/13 21:50:04'],
  ['respCode', '0'],
  ['isoCode', '0'],
  ['authCode', ''],
  ['acquirerInvoice', '0'],
  ['message', ''],
  ['isComplete', 'true'],
  ['isTimeout', 'false']
];

const obj = new Map(array);

console.log(obj.get('txnDate'));

【讨论】:

  • 别这样……太简单了^^
  • @Rick 我在这里很困惑。我刚刚在控制台中尝试了这个:array = [['a', 1],['b','two'],['c', [3,3,3]]],然后是obj = new Map(array);。但是,obj.aobj['a'] 都是未定义的。那么这如何实现目标呢?
  • @RickViscomi -- 好的。不知道 Map 对象。但是,我想说大多数人正在寻找的是获得一个常规的 JS 对象。
  • 不确定大多数人在寻找什么,但最初的问题是在给定属性 txnDate 的情况下寻找值 '2015/08/13 21:50:04',我认为这是最符合语义的方式。跨度>
  • @PA。 typeof new Map() // "object" :)
【解决方案5】:
arr.reduce((o, [key, value]) => ({...o, [key]: value}), {})

【讨论】:

    【解决方案6】:

    使用Object.fromEntries,您可以将Array 转换为Object

    var entries = [
      ['cardType', 'iDEBIT'],
      ['txnAmount', '17.64'],
      ['txnId', '20181'],
      ['txnType', 'Purchase'],
      ['txnDate', '2015/08/13 21:50:04'],
      ['respCode', '0'],
      ['isoCode', '0'],
      ['authCode', ''],
      ['acquirerInvoice', '0'],
      ['message', ''],
      ['isComplete', 'true'],
      ['isTimeout', 'false']
    ];
    var obj = Object.fromEntries(entries);
    console.log(obj);

    【讨论】:

    • 这很酷,请注意,在撰写本文时,它的状态是:草稿。评论是:ECMAScript 2019 中的初始定义。
    • 这是最好的答案。
    • 太棒了。让我想起了 ruby​​ 的 Hash[some_array] 功能。
    【解决方案7】:

    使用下面的方法可以轻松将数组转换为对象。

    var obj = {};
    array.forEach(function(e){
       obj[e[0]] = e[1]
    })
    

    这将使用第一个元素作为键,第二个元素作为每个元素的值。

    【讨论】:

      【解决方案8】:

      使用.reduce()的ES5版本

      const object = array.reduce(function(accumulatingObject, [key, value]) {
        accumulatingObject[key] = value;
        return accumulatingObject;
      }, {});
      

      【讨论】:

      • 这个怎么用?抱歉,javascript 新手,不知道如何调用它?
      • @PaulKenjora 其中const object = array.reduce ... array 是原始数组的变量名称,object 是您要为其分配新值的变量名称.它已经被调用,并将值分配给一个新变量object
      【解决方案9】:

      使用 Airbnb 代码风格的短 ES6 方式

      示例:

      const obj = arr.reduce((prevObj, [key, value]) => ({ ...prevObj, [key]: value }), {});
      

      【讨论】:

        【解决方案10】:

        用于此的新 JS API 是 Object.fromEntries(array of tuples),它适用于原始数组和/或地图

        【讨论】:

        • 提供一个代码示例,将您的建议与发布问题的用户的代码相结合,以使您的答案更有用
        【解决方案11】:

        在数组包含 JSON 数据的情况下最简单的方法:

        var obj = {};
        array.forEach(function(Data){
        obj[Data[0]] = Data[1]
        })
        

        【讨论】:

          【解决方案12】:

          我更推荐你使用 ES6 和完美的Object.assign() 方法。

          Object.assign({}, ...array.map(([ key, value ]) => ({ [key]: value })));
          

          这里发生了什么 - Object.assign() 什么都不做,只是从捐赠对象中获取 key:value 并将 pair 放入您的结果中。在这种情况下,我使用... 将新的array 拆分为乘对(映射后看起来像[{'cardType':'iDEBIT'}, ... ])。所以最后,新的{} 会从映射的array 的每对中接收每个key:property。

          【讨论】:

            【解决方案13】:

            你可以在 ES6 中使用数组 reduce 轻松做到这一点

            在本例中,我们创建了一个 reducer 函数并将一个对象“{}”作为初始值与 reducer 一起传递给 reduce 函数

            const arr =    [ [ 'cardType', 'iDEBIT' ],
              [ 'txnAmount', '17.64' ],
              [ 'txnId', '20181' ],
              [ 'txnType', 'Purchase' ],
              [ 'txnDate', '2015/08/13 21:50:04' ],
              [ 'respCode', '0' ],
              [ 'isoCode', '0' ],
              [ 'authCode', '' ],
              [ 'acquirerInvoice', '0' ],
              [ 'message', '' ],
              [ 'isComplete', 'true' ],
              [ 'isTimeout', 'false' ] ];
            
            const reducer = (obj, item) => {
              obj[item[0]] = item[1];
              return obj;
            };
            
            const result = arr.reduce(reducer, {});
            
            console.log(result);

            【讨论】:

              【解决方案14】:
              let obj ={'abc':123,'other':566};
              
              // first way
              let coll= Object.entries(obj).map(i=>Object.assign({'key':i[0],'value':i[1]}))
              
              results: coll => 
              0: {key: "abc", value: 123}
              1: {key: "other", value: 566}
              
              // second way
              let coll2= new Map(Object.entries(obj))
              results: coll2 =? 
              //[[Entries]]
              0: {"abc" => 123}
              1: {"other" => 566}
              

              【讨论】:

                猜你喜欢
                • 2019-01-14
                • 2019-12-02
                • 2021-02-14
                • 1970-01-01
                • 1970-01-01
                • 1970-01-01
                • 2017-08-25
                • 1970-01-01
                • 1970-01-01
                相关资源
                最近更新 更多