为了账号安全,请及时绑定邮箱和手机立即绑定

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

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

汪汪一只猫 2023-12-14 17:05:38
我需要将两个 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 循环?
查看完整描述

3 回答

?
斯蒂芬大帝

TA贡献1827条经验 获得超8个赞

最简单的方法可能是将.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]))

  )

)


查看完整回答
反对 回复 2023-12-14
?
慕雪6442864

TA贡献1812条经验 获得超5个赞

如果您对属性进行硬编码而不是查看,您可以摆脱内部循环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);

}

我用 11k 个项目对其进行了测试,在 Chrome 中运行时间约为 5 毫秒。对于 90k 项,仍然只需要大约 30 毫秒。


查看完整回答
反对 回复 2023-12-14
?
FFIVE

TA贡献1797条经验 获得超6个赞

您可以放弃这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)

    }

}


查看完整回答
反对 回复 2023-12-14
  • 3 回答
  • 0 关注
  • 65 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信