基于对象属性排序数组的冒泡排序函数无法运行的问题排查
问题分析与解决方案
早上好!咱们来一步步拆解你的冒泡排序函数为啥不能正常工作,然后把它修好~
主要问题点
- 属性访问方式错误:你用了
arr[j].property这种点语法,但这里的property是函数参数变量,点语法会把它当成字符串字面量去访问对象的"property"属性(而不是你传入的"wheel"或"id"),正确的做法应该是用方括号语法arr[j][property]来动态访问属性。 - 数组越界问题:内层循环
j < arr.length会导致当j等于数组最后一个索引时,arr[j+1]变成undefined,和undefined比较会出现逻辑错误;而且冒泡排序的内层循环其实只需要遍历到arr.length - i - 1(每一轮排序都会把最大/最小的元素“冒”到末尾,后面的元素已经是有序的了)。 - 缺少必填参数检查:你调用
bubbleSort(data)时没有传入property参数,这时候函数里的property是undefined,根本没法正确访问对象属性。要么给property设置合理默认值,要么在函数开头检查参数是否传入。 - 排序逻辑冗余:升序和降序的循环逻辑几乎一样,其实可以把核心逻辑抽出来,通过条件判断控制排序方向,减少重复代码。
修正后的完整代码
const data = [ { "color": "Blue", "door": 3, "wheel": 3, "year": 2005, "brand": "GMC", "sold": false, "owner": "Chalmers Boobyer", "motor": 1.7, "assembled": "09/08/2022" }, { "color": "Indigo", "door": 4, "wheel": 4, "year": 1996, "brand": "Lincoln", "sold": true, "owner": "Morten Coffin", "motor": 1.7, "assembled": "26/08/2021" } ]; function bubbleSort(arr, ord='asc', property) { // 检查必要参数,避免静默错误 if (!property) { console.error('请传入要排序的对象属性名!'); return [...arr]; // 返回原数组副本,不修改原数组 } // 创建数组副本,避免直接修改传入的原数组(可选但推荐) const sortedArr = [...arr]; const length = sortedArr.length; for (let i = 0; i < length; i++) { // 内层循环只遍历未排序的部分 for (let j = 0; j < length - i - 1; j++) { const currentVal = sortedArr[j][property]; const nextVal = sortedArr[j+1][property]; // 根据排序方向判断是否交换元素 if ((ord === 'asc' && currentVal > nextVal) || (ord === 'desc' && currentVal < nextVal)) { // 用解构赋值交换元素,更简洁 [sortedArr[j], sortedArr[j+1]] = [sortedArr[j+1], sortedArr[j]]; } } } return sortedArr; } // 示例调用:根据wheel属性升序排序 console.log(bubbleSort(data, 'asc', 'wheel')); // 根据year属性降序排序 console.log(bubbleSort(data, 'desc', 'year'));
额外优化说明
- 合并了升序/降序的排序逻辑,用一个条件判断处理两种情况,减少代码重复。
- 新增参数检查,当未传入
property时给出明确提示,避免无意义的排序。 - 采用数组副本进行排序,避免直接修改原数组(如果需要修改原数组,可以去掉副本创建步骤,直接操作
arr)。 - 使用解构赋值交换元素,比临时变量写法更简洁直观。
内容的提问来源于stack exchange,提问作者Eduardo S
相关产品推荐
相关产品推荐

