【问题标题】:How to convert an array [] to a series of { key: value } paired objects?如何将数组 [] 转换为一系列 { key: value } 配对对象?
【发布时间】:2020-04-09 11:59:13
【问题描述】:

我正在寻找改变这个...

[
  [ 'market', 'type', 'timeframe', 'proximal', 'distal', 'risk', 'tradeable' ], // object keys
  [ 'AD', 'DZ', 'daily', '0.6375', '0.6283', '$920.00', 'FALSE' ] // key values
]

进入这个...

[ 
  { 
    market: 'AD', 
    type : 'DZ', 
    timeframe: 'daily', 
    proximal: '0.6375', 
    distal: '0.6283', 
    risk: '$920.00', 
    tradeable: 'FALSE' 
  }
]

到目前为止,这就是我所拥有的......

// each element of the array (I call a 'zone')
data.forEach(z => {

  // each element inside the 'zone'
  z.forEach(e => {

    // headings to object keys, where k = key and v = value
    const obj = headings.reduce((k,v) => (k[v]="",k),{})

    console.log(obj)
  })
})

console.log(obj) 将其输出到控制台:

Object {
  distal: "",
  market: "",
  proximal: "",
  risk: "",
  timeframe: "",
  tradeable: "",
  type: ""
}

我只是不知道如何将值放入这些密钥对中,请帮助!!

提前致谢,

山姆

【问题讨论】:

  • 为什么要将结果对象作为数组中的唯一元素?
  • 对不起,我不确定我是否理解你的问题@Bergi
  • 您的“into this...”所需的结果有一个数组文字 ([ … ]),我看不出有任何需要(并且没有尝试在您的代码)
  • 哦,我了解@Bergi,因为这将是对象的array,为了简洁起见,我只是没有在我的问题中包含完整的data 数组

标签: javascript arrays object functional-programming data-manipulation


【解决方案1】:

使用 reduce,reduce 对数组的每个元素运行一个函数,并在每次迭代时返回一个累加器。在这种情况下,起始累加器是空对象 {},在每次迭代中,我们将键添加到累加器,其值来自另一个数组中的当前索引。

const data = [
  [ 'Market', 'Type', 'Timeframe', 'Proximal', 'Distal', 'Risk', 'Tradeable' ],
  [ 'AD', 'DZ', 'daily', '0.6375', '0.6283', '$920.00', 'FALSE' ],
  [ 'EC', 'SZ', 'daily', '1.13475', '1.13895', '$525.00', 'FALSE' ],
  [ 'DXY', 'DZ', '60 min', '96.85', '96.76', '', 'FALSE' ]
];

const match = (keys, values) => keys.reduce((result, key, index) => {
  result[key] = values[index];
  return result;
}, {});

const matchAll = data => data.reduce((results, current, index) => {
  if (index) {
    results.push(match(data[0], data[index]));
  }
  return results;
}, []);

console.log(matchAll(data));

【讨论】:

  • 为什么在这里使用reduce-reduce有一个特定的功能,而你没有使用它?
  • Reduce 将数组缩减为结果,这正是我在这里所做的。
  • 哦,错过了您使用初始参数的事实。这是更好的解决方案。
  • 这正是我想要的,谢谢@AdrianBrand!如果您愿意,请您准确解释您的代码在做什么?
  • 我会在答案中添加描述
【解决方案2】:

尝试像这样使用它:

function reinterpret(data) {
  let result = {}
  data[0].forEach((key, index) => {
    result[key] = data[1][index];
  });
  return [result];
}

【讨论】:

    【解决方案3】:

    您可以使用简单的forEach,而不是使用reduce。据我了解,您的第一个数组的索引映射到您的第二个数组。所以就做这样的事情吧。

    let arrays = [
      [ 'market', 'type', 'timeframe', 'proximal', 'distal', 'risk', 'tradeable' ], // object keys
      [ 'AD', 'DZ', 'daily', '0.6375', '0.6283', '$920.00', 'FALSE' ] // key values
    ]
    
    let output = {};
    arrays[0].forEach((item, index) => {
      output[item] = arrays[1][index];
    });
    
    console.log([output]);

    【讨论】:

      【解决方案4】:

      这也有效

      let arrays = [
        ["market", "type", "timeframe", "proximal", "distal", "risk", "tradeable"], // object keys
        ["AD", "DZ", "daily", "0.6375", "0.6283", "$920.00", "FALSE"] // key values
      ];
      
      const keys = 0;
      const values = 1;
      
      const objKeys = arrays[keys].map((item, index) => {
        return { [item]: arrays[values][index] };
      });
      
      const obj = [Object.assign({}, ...objKeys)];
      
      console.log(obj);

      【讨论】:

        【解决方案5】:

        let arr = [
            ['market', 'type', 'timeframe', 'proximal', 'distal', 'risk', 'tradeable'], // object keys
            ['AD', 'DZ', 'daily', '0.6375', '0.6283', '$920.00', 'FALSE'] // key values
        ]
        
        var result = [];
        var obj = {};
        arr.forEach((item) => {
            if (arr.indexOf(item) == 0) {
                for (var i = 0; i < item.length; i++) {
                    obj[item[i]] = arr[1][i];
                }
                result.push(obj);
            }
        })
        
        console.log(result);

        【讨论】:

          【解决方案6】:

          调用大量函数看起来很优雅,但如果你关心速度,那么一个简单的循环就是赢家

          const arrays =[
            [ 'market', 'type', 'timeframe', 'proximal', 'distal', 'risk', 'tradeable' ], // object keys
            [ 'AD', 'DZ', 'daily', '0.6375', '0.6283', '$920.00', 'FALSE' ] // key values
          ];
          
          function parallelArraysToObject([keys, values]) {
            const result = {};
            for (let i = 0; i < keys.length; ++i) {
              result[keys[i]] = values[i];
            }
            return result;
          }
          
          console.log(parallelArraysToObject(arrays));

          注意:fromEntries 解决方案的代码是here,reduce 解决方案的代码是here

          虽然我们在这里假设数据来自excel之类的东西,第一行是列名。

          const data = [
            [ 'Market', 'Type', 'Timeframe', 'Proximal', 'Distal', 'Risk', 'Tradeable' ],
            [ 'AD', 'DZ', 'daily', '0.6375', '0.6283', '$920.00', 'FALSE' ],
            [ 'EC', 'SZ', 'daily', '1.13475', '1.13895', '$525.00', 'FALSE' ],
            [ 'DXY', 'DZ', '60 min', '96.85', '96.76', '', 'FALSE' ]
          ];
          
          const parallelArraysToObject = (keys, values) => {
            const result = {};
            for (let i = 0; i < keys.length; ++i) {
              result[keys[i]] = values[i];
            }
            return result;
          };
          
          const rowsToArraysOfObjects = data => {
            const results = [];
            for (let i = 1; i < data.length; ++i) {
              results.push(parallelArraysToObject(data[0], data[i]));
            }
            return results;
          };
          
          console.log(rowsToArraysOfObjects(data));

          循环展开也是如此(好吧,也许没有展开,但没有嵌套函数调用)

          const data = [
            [ 'Market', 'Type', 'Timeframe', 'Proximal', 'Distal', 'Risk', 'Tradeable' ],
            [ 'AD', 'DZ', 'daily', '0.6375', '0.6283', '$920.00', 'FALSE' ],
            [ 'EC', 'SZ', 'daily', '1.13475', '1.13895', '$525.00', 'FALSE' ],
            [ 'DXY', 'DZ', '60 min', '96.85', '96.76', '', 'FALSE' ]
          ];
          
          const rowsToArraysOfObjects = data => {
            const results = [];
            const keys = data[0];
            for (let i = 1; i < data.length; ++i) {
              const values = data[i];
              const record = {};
              for (let j = 1; j < keys.length; ++j) {
                record[keys[j]] = values[j];
              }
              results.push(record);
            }
            return results;
          };
          
          console.log(rowsToArraysOfObjects(data));

          我们可以看到,流行的编码风格通常不是很注重性能。根据浏览器的不同,double reduce 最多慢 7 倍,至少慢 25%。

          【讨论】:

          • 你用什么来获得跨浏览器分析?
          • jsperf- 最有可能自己启动不同的浏览器
          【解决方案7】:

          在现代浏览器中,您可以使用Object.fromEntries

          const kvs =[
            [ 'market', 'type', 'timeframe', 'proximal', 'distal', 'risk', 'tradeable' ], // object keys
            [ 'AD', 'DZ', 'daily', '0.6375', '0.6283', '$920.00', 'FALSE' ] // key values
          ];
          
          const ob = Object.fromEntries(kvs[0].map((key, ndx) => [key, kvs[1][ndx]]));
          
          console.log(ob);

          此解决方案不是最快的。 A fast solution is a simple loop。重要的是要知道什么时候速度很重要。如果您每秒执行一百万次,那么您当然应该使用最快的解决方案。如果您偶尔这样做(例如在用户单击“更多数据”时解析来自服务器的响应),那么最快显然不是优先事项。另一方面,如果您打算将代码放入库中,则应该使用最快的合理解决方案,因为您不知道用户将如何使用您的代码。当然,我说的是最快的合理解决方案,因为有时快速解决方案可能会令人费解。幸运的是a fast solution 是非常基本的代码。

          【讨论】:

          • index 传统上缩写为i,而不是ndx
          • 构建一个中间数组而不是直接生成对象是相当低效的
          • 同一用户的多个单独答案是 S.O. 的正常功能。答案不同,所以它们是不同的答案。如果这不是它应有的工作方式,则该功能将不存在。
          • 我认为只有将它和 reduce 版本结合在一个答案中才有意义。否则,您引用 fromEntries 的评论没有任何意义,因为它也适用于 reduce。我想现在我会离开它。
          猜你喜欢
          • 2022-06-12
          • 1970-01-01
          • 2018-12-13
          • 2021-03-17
          • 2014-10-12
          • 2014-04-23
          • 1970-01-01
          • 2015-03-22
          • 1970-01-01
          相关资源
          最近更新 更多