NodeJS中向对象中间插入属性并按数字序号正确排序的方法
问题根因
- 无参数调用
sort()时,默认将元素转为字符串按字典序排序:对比item10和item2时,逐字符比对到item后的第一个字符,1的字符编码小于2,就会判定item10排在item2前,造成顺序错乱。 - 普通对象新增可枚举属性时,默认会追加到属性枚举列表的末尾,不会自动插入到序号对应的中间位置。
- 你之前的代码直接把整个数组变量
myObject赋值为排序后的对象,会丢失原数组里的第二个元素,属于变量覆盖问题。
实现代码
自定义排序比较函数,提取属性名中的数字部分转成数值类型比较大小,排序后转回对象替换数组内的第一个元素即可:
let myObject = [ { 'item1' : 'string1', 'item2' : 'string2', 'item3' : 'string3', 'item4' : 'string4', 'item5' : 'string5', 'item6' : 'string6', 'item7' : 'string7', 'item8' : 'string8', 'item10' : 'string10', 'item11' : 'string11', 'item12' : 'string12', 'item14' : 'string14', 'item15' : 'string15' }, { 'item16' : 'string16', 'item17' : 'string17', 'item18' : 'string18', 'item19' : 'string19', 'item20' : 'string20', 'item21' : 'string21', 'item22' : 'string22', 'item23' : 'string23', 'item25' : 'string25', 'item26' : 'string26', 'item27' : 'string27', 'item29' : 'string29', 'item30' : 'string30' } ] // 新增缺失属性 myObject[0].item9 = 'string9' myObject[0].item13 = 'string13' // 按属性名后的数字数值升序排序 myObject[0] = Object.fromEntries( Object.entries(myObject[0]).sort(([keyA], [keyB]) => { const numA = Number(keyA.slice(4)) // 截取item之后的部分转数字 const numB = Number(keyB.slice(4)) return numA - numB }) ) console.log(myObject[0])
运行后输出的myObject[0]就是你期望的、属性严格按item1到item15升序排列的对象,同时原数组的第二个元素不会丢失。
补充说明
- 上述代码里用
slice(4)截取属性名第4位之后的内容,是因为item固定占4个字符,比正则替换的执行效率更高;如果属性前缀后续可能变化,换成正则提取数字的写法也可以,比如const numA = Number(keyA.match(/\d+/)[0])。 - ES6及之后版本中,
Object.entries、Object.fromEntries、对象属性枚举顺序的规则是标准化的,只要环境支持ES6,排序后的属性顺序在遍历、打印时都会保持一致。
内容的提问来源于stack exchange,提问作者Rafael Rocha
相关产品推荐
相关产品推荐

