使用reduce()合并数组生成对象时顺序异常问题求助
为啥用reduce合并数组得到的对象,键的顺序乱了?
你这个问题其实和reduce()本身没啥关系——它确实是老老实实按数组从左到右的顺序执行回调的,问题出在JavaScript普通对象的键的存储规则上。
为啥顺序会乱?
早期的JavaScript规范里,用{}创建的普通对象,根本不保证键的遍历顺序和你插入的顺序一致。虽然ES6之后对这个规则做了明确,但有个坑:如果键是能被解析成整数的字符串(比如"10"、"200"),会被优先排前面,还按数值大小排序;非整数的字符串键才按插入顺序来。但在一些旧的JS引擎或者特定运行环境里,哪怕是非整数的字符串键,也可能出现顺序乱掉的情况,你遇到的就是这种。
怎么解决?
要是你必须严格保证键值对的顺序,有两个靠谱的办法:
1. 用Map代替普通对象
Map是ES6新增的结构,它会严格按照你插入键的顺序来保存和遍历:
var code = testValue.reduce(function(map, value, index) { map.set(testHeaders[index], value); return map; }, new Map());
之后要是需要转成你要的字符串格式,直接遍历Map拼接就行:
let resultStr = '{ '; for (const [key, value] of code) { resultStr += `${key} = ${value}, `; } // 删掉最后多余的逗号和空格 resultStr = resultStr.slice(0, -2) + ' }';
2. 直接拼接目标字符串
既然你最终要的是特定格式的字符串,那完全可以跳过创建对象这一步,直接遍历数组拼接:
var pairs = testHeaders.map((header, index) => `${header} = ${testValue[index]}`); var resultStr = `{ ${pairs.join(', ')} }`;
这种方式完全由你掌控顺序,绝对不会出乱子。
额外提一句
你说要把这个字符串上传到BigQuery,得注意一下BigQuery的表结构是不是依赖这个字符串的顺序。如果BigQuery是按字段名匹配数据的,那其实对象的顺序根本不影响;但要是必须保证顺序,上面的两种方案都能完美解决你的问题。
内容的提问来源于stack exchange,提问作者Steffen Davidsen
相关产品推荐
相关产品推荐

