微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

有效地将 JavaScript 键和值数组转换为对象

如何解决有效地将 JavaScript 键和值数组转换为对象

我需要将两个 JavaScript 数组转换为一个对象列表。一个输入数组表示输出对象的键,另一个包含它的值(以及一些其他信息,与此问题无关)。

示例数据:

let theKeys = ['firstName','lastName','city'];
let theValues = [{data: [['John','Smith','New York'],['Mike','Doe','Chicago'],...
                        ],otherStuff: ...}
                ];

以上所需的输出

output = [{
            firstName: 'John',lastName: 'Smith',city: 'New York'
          },{
            firstName: 'Mike',lastName: 'Doe',city: 'Chicago',},...
         ]

(这只是一个例子,我的实际数据来自 REST 响应,内容和长度可能会有所不同。我正在使用一个显示表格数据的 Vue 应用程序。)

下面我现有的代码适用于少量数据,但会使所有浏览器崩溃或挂起以处理大量数据。

return this.theValues.flatMap(results => {
  let jsonified = [];

  for (let v = 0; v < results.theValues.length; v++) {
    let singleJson = {}; 

    for (let k = 0; k < this.theKeys.length; k++) {
      let key = this.theKeys[k];
      singleJson[key] = results.data[v][k];
    }

    jsonified.push(singleJson);
  }

  return jsonified;
});

对于少至几千个结果,这需要几分钟才能运行。我怎样才能让它更快?是否有一些我遗漏的操作可以让我避免嵌套的 for 循环?

解决方法

最简单的方法可能是将值 .map 转换为键值元组并对其调用 Object.fromEntries

const theKeys = ['firstName','lastName','city'];
const theValues = [{
  data: [
    ['John','Smith','New York'],['Mike','Doe','Chicago']
  ]
}];

console.log(
  theValues[0].data.map(e =>
    Object.fromEntries(e.map((e,i) => [theKeys[i],e]))
  )
)

,

如果您对属性进行硬编码而不是查看 theKeys,您可以摆脱内部循环,但我怀疑您是否想要那样。您唯一真正不需要的是 flatMap。无论如何,大多数通用数组方法的速度并不出名(例如,forEach 通常比普通的 for 循环慢)。

FWIW,这似乎表现良好:

let result = [];
for (let i = 0; i < theValues[0].data.length; i++) {
    let resultObj = {};
    for (let j = 0; j < theKeys.length; j++) {
        resultObj[theKeys[j]] = theValues[0].data[i][j];
    }
    result.push(resultObj);
}

我用 11,000 项测试了它,它在 Chrome 中运行了大约 5 毫秒。有 90k 个项目,它仍然只花了大约 30 毫秒。

,

你可以放弃 flatMap 这应该可以节省一些性能,只需用简单的循环来做所有事情:

const result = []

for (const v of theValues) {
    for (const entry of v.data) {
        const obj = {}
        for (let i = 0; i < entry.length; i++) {
            obj[theKeys[i]] = entry[i]
        }
        result.push(obj)
    }
}

编辑:微优化

const result = []
const keysLength = theKeys.length

for (let i = theValues.length - 1; i >= 0; i--) {
    const data = theValues[i].data
    for (let j = data.length - 1; j >= 0; j--) {
        const entry = data[j]
        const obj = {}

        for (let k = keysLength - 1; k >= 0; k--) {
            obj[theKeys[k]] = entry[k]
        }
        result.push(obj)
    }
}

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐


Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其他元素将获得点击?
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。)
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbcDriver发生异常。为什么?
这是用Java进行XML解析的最佳库。
Java的PriorityQueue的内置迭代器不会以任何特定顺序遍历数据结构。为什么?
如何在Java中聆听按键时移动图像。
Java“Program to an interface”。这是什么意思?