简体   繁体   English

有效地将 JavaScript 键和值 arrays 转换为 object

[英]Efficiently converting JavaScript key and value arrays to object

I need to turn two JavaScript arrays into a list of objects.我需要将两个 JavaScript arrays 变成对象列表。 One of the input arrays represents the keys of the output object and the other contains its values (alongside some other information, not relevant to this question).输入 arrays 之一表示 output object 的键,另一个包含其值(以及其他一些信息,与此问题无关)。

Example data:示例数据:

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

Desired output for above:以上所需的 output:

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

(This is just an example, my actual data comes from REST responses and can vary in content and length. I'm working with a Vue app that displays tabular data.) (这只是一个示例,我的实际数据来自 REST 响应,内容和长度可能会有所不同。我正在使用显示表格数据的 Vue 应用程序。)

My existing code, below, works for small amounts of data but makes all browsers crash or hang for larger amounts of data.下面我现有的代码适用于少量数据,但会使所有浏览器崩溃或挂起大量数据。

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 as few as a couple thousand results, this takes minutes to run.对于几千个结果,这需要几分钟才能运行。 How can I make it faster?我怎样才能让它更快? Is there some operation I'm missing that will allow me to avoid the nested for loop?是否有一些我遗漏的操作可以让我避免嵌套的 for 循环?

The easiest way maybe to .map the values into key-value tuples and call Object.fromEntries on it:最简单的方法可能是将.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])) ) )

You can get rid of the inner loop if you hardcode the properties instead of looking at theKeys , but I doubt you'd want that.如果您对属性进行硬编码而不是查看theKeys ,则可以摆脱内部循环,但我怀疑您是否想要这样做。 The only thing you don't really need is the flatMap .您唯一不需要的是flatMap Most of the generic array methods aren't known for their speed, anyway ( forEach is usually slower than a plain for loop, for example).无论如何,大多数通用数组方法的速度并不为人所知(例如, forEach通常比普通for循环慢)。

FWIW, this seems to perform fine: 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);
}

I tested it with 11k items and it ran in about 5 miliseconds in Chrome.我用 11k 个项目对其进行了测试,它在 Chrome 中运行了大约 5 毫秒。 With 90k items, it still only took about 30ms.对于 90k 个项目,它仍然只需要大约 30 毫秒。

You can forego the flatMap which should save you some performance, just do everything with plain loop:您可以放弃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)
    }
}

EDIT: micro-optimizations编辑:微优化

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)
    }
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM