【问题标题】:How to converting an array to a dictionary in Javascript (also re-order columns into rows)?如何在Javascript中将数组转换为字典(也将列重新排序为行)?
【发布时间】:2018-12-21 14:53:47
【问题描述】:

我有以下数组:

[
  [o1, c1, h1, l1 ,t1],
  [o2, c2, h2, l2, t2],
  ...
  [oN, cN, hN, lN, tN]
]

我需要将其转换为按以下方式构造的对象:

{
  open:   [o1,o2,o3,o4,o5,o6,o7,o8, ... oN],
  close:  [c1,c2,c3,c4,c5,c6,c7,c8, ... cN],
  high:   [h1,h2,h3,h4,h5,h6,h7,h8, ... hN],
  low:    [l1,l2,l3,l4,l5,l6,l7,l8, ... lN],
  time:   [t1,t2,t3,t4,t5,t6,t7,t8, ... tN]
}

所以这意味着我需要解决的另一个问题是将列重新组织成行。

以下是适合我的代码:

function convertData(rawDataArray) {
  [open, close, high, low, timesignature] = [
    [],
    [],
    [],
    [],
    []
  ];
  var arrayLength = rawDataArray.length;
  for (var i = 0; i < arrayLength; i++) {
    open.push(rawDataArray[i][1])
    close.push(rawDataArray[i][2])
    high.push(rawDataArray[i][3])
    low.push(rawDataArray[i][4])
    timesignature.push(rawDataArray[i][0])
  }
  return {
  	open: open,
    close: close,
    high: high,
    low: low,
    timeSignature: timesignature
  }
}

但是,我的解决方案在我看来是一个笨重且不太优雅的解决方案。我很想知道如何以更有效的方式编写此代码。

【问题讨论】:

  • 如果您正在寻找性能,您的代码可能是该问题的最佳解决方案,因为按位置访问数组的复杂度为 O(1)。如果您正在寻找紧凑性和/或可读性,您可以使用一些 mapreduce 来代替
  • 我的印象是.map 之类的方法也被设计为性能优化。不是这样吗?顺便说一句,我接受了基于.map 的答案。

标签: javascript data-structures javascript-objects


【解决方案1】:

我认为优雅是指更易于阅读的代码,而不一定是更快的性能。这就是map() 派上用场的地方,因为它将笨重的 for 循环减少到一行。

function convertData(rawDataArray) {
    return {
        open: rawDataArray.map(i=>i[0]),
        close: rawDataArray.map(i=>i[1]),
        high: rawDataArray.map(i=>i[2]),
        low: rawDataArray.map(i=>i[3]),
        timeSignature: rawDataArray.map(i=>i[4])
    }
}

【讨论】:

    【解决方案2】:

    let row =[
      ["o1", "c1", "h1", "l1","t1"],
      ["o2", "c2", "h2", "l2", "t2"]
    ]
    const extractIndex = (ind,data)=> data.map(e=>e[ind]) 
    const convertDataNew = (rawDataArray)=> {
      return {
        open: extractIndex(0,rawDataArray),
        close: extractIndex(1,rawDataArray),
        high: extractIndex(2,rawDataArray),
        low: extractIndex(3,rawDataArray),
        timeSignature: extractIndex(4,rawDataArray)
      }
    
    }
    
    
    console.log(convertDataNew(row))

    【讨论】:

    • 谢谢。我有两个答案。非常艰难的决定。我想我会选择@fjch1997 的回答。
    【解决方案3】:

    您可以获取密钥并将它们用作属性访问器的一部分以推送值。

    function convertData(rawDataArray) {
        var keys = ['open', 'close', 'high', 'low', 'time'],
            result = Object.assign(...keys.map(k => ({ [k]: [] })));
    
        rawDataArray.forEach(a => keys.forEach((k, i) => result[k].push(a[i])));
        return result;
    }
    

    【讨论】:

    • 谢谢,这也是一个有趣的解决方案。
    • 我不明白。 k 未在 lambda 表达式中定义 a =&gt; k.forEach(...)
    • 对不起。应该是keys
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2019-08-14
    • 2020-03-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-10-28
    相关资源
    最近更新 更多