如何在JavaScript中使用方括号表示法对动态嵌套对象排序
解决嵌套对象数组按动态配置字段排序的问题
你的代码在处理嵌套字段时失效,核心原因是a[sortDef.fieldName]会直接尝试访问对象的director.name属性(而非先取director再取其name属性),而这个属性并不存在,导致获取的值为undefined,排序逻辑自然无法正常工作。
解决方案步骤
- 编写一个工具函数,用于解析嵌套字段路径(如
director.name),逐层获取对象的属性值。 - 在排序回调中使用该工具函数获取目标字段值,再根据字段类型(字符串/数字)和排序顺序处理比较逻辑。
完整代码示例
const mov = [ { "id": "006", "name": "Schindler's List", "year": 1993, "director": { "name": "Steven Spielberg", "DOB": "01/28/1946" }, "type": 1 }, { "id": "001", "name": "The Shawshank Redemption", "year": 1994, "director": { "name": "Frank Darabont", "DOB": "01/28/1959" }, "type": 1 } ]; const sortDef = { fieldName: 'director.name', sortingOrder: 'desc' }; // 解析嵌套路径,获取属性值 function getNestedValue(obj, path) { return path.split('.').reduce((current, key) => { return current && current[key] !== undefined ? current[key] : undefined; }, obj); } // 执行排序 mov.sort((a, b) => { const valA = getNestedValue(a, sortDef.fieldName); const valB = getNestedValue(b, sortDef.fieldName); // 字符串类型比较(忽略大小写) if (typeof valA === 'string' && typeof valB === 'string') { const lowerA = valA.toLocaleLowerCase(); const lowerB = valB.toLocaleLowerCase(); if (lowerA > lowerB) return sortDef.sortingOrder === 'desc' ? -1 : 1; if (lowerA < lowerB) return sortDef.sortingOrder === 'desc' ? 1 : -1; } // 数字类型比较 else if (typeof valA === 'number' && typeof valB === 'number') { if (valA > valB) return sortDef.sortingOrder === 'desc' ? -1 : 1; if (valA < valB) return sortDef.sortingOrder === 'desc' ? 1 : -1; } // 值相等时返回0 return 0; }); console.log(mov);
代码说明
getNestedValue函数通过将字段路径按.拆分,使用reduce逐层遍历对象,最终返回目标属性值,兼容平级和嵌套字段。- 排序回调中针对字符串和数字做了区分处理:字符串比较会忽略大小写,数字直接做数值比较,同时根据
sortingOrder参数调整返回值的正负,实现升序或降序。 - 补充了值相等时返回0的逻辑,符合数组
sort方法的规范。
内容的提问来源于stack exchange,提问作者Arkamit
相关产品推荐
相关产品推荐

