高效地将JavaScript键和值数组转换为对象
我需要将两个JavaScript数组转换为对象列表。其中一个输入数组表示输出对象的键,另一个包含其值(以及一些与此问题无关的其他信息) 示例数据:高效地将JavaScript键和值数组转换为对象,javascript,arrays,performance,vue.js,vuetify.js,Javascript,Arrays,Performance,Vue.js,Vuetify.js,我需要将两个JavaScript数组转换为对象列表。其中一个输入数组表示输出对象的键,另一个包含其值(以及一些与此问题无关的其他信息) 示例数据: let theKeys = ['firstName', 'lastName', 'city']; let theValues = [{data: [['John', 'Smith', 'New York'], ['Mike', 'Doe', 'Chicago'],
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;
});
返回此.theValues.flatMap(结果=>{
让jsonified=[];
for(设v=0;v
对于几千个结果,这需要几分钟来运行。我怎样才能使它更快?是否缺少一些操作可以避免嵌套for循环?最简单的方法可能是
。将值映射到键值元组中,并调用对象。其中的fromEntries
:
const theKeys=['firstName','lastName','city'];
常量值=[{
数据:[
[“约翰”、“史密斯”、“纽约”],
['Mike','Doe','Chicago']
]
}];
console.log(
值[0].data.map(e=>
Object.fromEntries(e.map((e,i)=>[theKeys[i],e]))
)
)
如果您硬编码属性而不是查看键,则可以去掉内部循环,但我怀疑您是否希望这样做。你唯一真正不需要的就是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);
}
let result=[];
for(设i=0;i<值[0]。data.length;i++){
设resultObj={};
for(设j=0;j
我测试了11k个项目,它在Chrome上运行了大约5毫秒。对于90k个项目,仍然只需要30毫秒。您可以放弃平面图,这将为您节省一些性能,只需使用普通循环即可:
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)
}
}
此属性的大小是多少。该值也是vue中的计算属性吗?它会有所不同。如果是7号或18号,一切都很好。如果是20429,我就有问题了。它不是计算出来的,它是从远程服务器返回的数据。包括平面图之前的console.time('test')
,以及返回之前的console.timeEnd('test')
,以查看经过的时间。我把它缩小到了对值的调用,这实际上是我正在使用的组件的一个特性。我用Math.random()
替换了它,一切都变得飞快。我想现在是时候问一个新问题了,更多地关注Vue。@WashingtonGuedes仅供参考,以防您仍然感兴趣,我最后问了一个问题:此代码在我的应用程序中生成正确的结果,但在29851行上运行需要255388ms。有些奇怪的事情正在发生。
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)
}
}