如何对含空值/未定义属性的对象数组按属性排序?
解决含空值的多类型字段排序问题
问题分析
你当前的排序函数处理字符串字段时,因大小写敏感导致排序混乱;同时空值(null/undefined)的处理逻辑未覆盖全场景,也没做到不同类型字段的兼容。
修复后的代码
const arr2 = [ { "Id": 1, "firstName": "tommy", "surname": "JONS", }, { "Id": 2, "firstName": "arnaud", "surname": "browny", }, { "Id": 3, "firstName": null, "surname": null, }, { "Id": 4, "firstName": "EMILY", "surname": "BOEKOEROSHE", } ]; function _copyAndSort<T>(items: T[], columnKey: string, isSortedDescending?: boolean): T[] { const key = columnKey as keyof T; return [...items].sort((a, b) => { // 统一处理空值:null/undefined 标记为特殊值,确保排最后 const valA = a[key] ?? '__EMPTY__'; const valB = b[key] ?? '__EMPTY__'; // 空值排序逻辑:如果其中一个是空值,直接确定顺序 if (valA === '__EMPTY__' && valB !== '__EMPTY__') { return isSortedDescending ? -1 : 1; } if (valB === '__EMPTY__' && valA !== '__EMPTY__') { return isSortedDescending ? 1 : -1; } // 非空值处理:字符串转小写比较,数字直接比较 let compareResult = 0; if (typeof valA === 'string' && typeof valB === 'string') { compareResult = valA.toLowerCase().localeCompare(valB.toLowerCase()); } else if (typeof valA === 'number' && typeof valB === 'number') { compareResult = valA - valB; } else { // 其他类型默认按原始值比较 compareResult = valA > valB ? 1 : valA < valB ? -1 : 0; } // 处理降序反转结果 return isSortedDescending ? -compareResult : compareResult; }); } // 按firstName升序排序 const sortedByName = _copyAndSort(arr2, "firstName", false); console.table(sortedByName); // 按Id升序排序 const sortedById = _copyAndSort(arr2, "Id", false); console.table(sortedById);
关键改进点
- 空值统一处理:用
??运算符把null/undefined替换为特殊标记__EMPTY__,确保这类值始终排在最后,不管升序降序 - 字符串大小写不敏感:把字符串转成小写后用
localeCompare比较,比直接用</>更可靠,还支持多语言排序 - 多类型兼容:分别处理字符串和数字类型的比较逻辑,避免类型不匹配导致的错误
- 清晰的排序逻辑:拆分空值判断、类型比较、降序反转三个步骤,代码更易读和维护
运行结果
按firstName升序排序后,结果为:
arnaud, EMILY, tommy, null
按Id升序排序结果保持正常:
Id:1, Id:2, Id:3, Id:4
内容的提问来源于stack exchange,提问作者user20377051
相关产品推荐
相关产品推荐

