题目描述
咱们就开门见山,直接来看题目~
补充以下代码,实现拍平数组并排序功能
// [1, 2, [4, 3], [[5, 6], 7]] 得到 [1,2,3,4,5,6,7,....]
const flatAndSort = (arr) => {
// .....
}
思路
既然是拍平并排序,咱们就分开两步来,先把原数组进行拍平,然后再对拍平数组排序
那么如何拍平呢
我的思路就是另外开辟一个数组,然后遍历数组所有元素,若该元素不是数组,则直接添加到新数组里,若该元素是数组,则继续递归拍平该元素.....
代码如下:(这里我用了数组的reduce方法来遍历数组)
const flattenArr = (arr: any[]): number[] => {
//返回的是最后拍平的数组
return arr.reduce((acc: number[], item) => {
// 如果当前元素是数组,递归拍平
if (Array.isArray(item)) {
acc.push(...flattenArr(item))
}else {
// 否则直接添加到结果数组
acc.push(item)
}
return acc
}, [])
}
那么如何排序呢
最简单的当然就是使用数组的sort方法
flattenedArr.sort((a, b) => a - b)
当然你也可以自己实现一个排序算法,例如冒泡排序,快速排序,这里就不列举了。
既然刚好用到了数组的sort方法,那就带大家复习一下数组的sort方法
默认情况下
默认情况下,sort 方法会将数组元素转换为字符串,然后按照 字典序(Unicode 码点顺序) 进行排序。
const arr = [10, 5, 20, 1];
arr.sort();
console.log(arr); // 输出: [1, 10, 20, 5]
默认的字典序排序可能会导致数字排序不符合预期(如 10 排在 5 前面)
但是默认排序规则适合字符串排序
const arr = ['banana', 'apple', 'cherry'];
arr.sort();
console.log(arr); // 输出: ['apple', 'banana', 'cherry']
自定义排序规则
sort 方法可以接受一个 比较函数(compare function) 作为参数,用于定义排序规则。
比较函数的规则:
- 比较函数接受两个参数
a和b,分别表示当前比较的两个元素。 - 返回值决定排序顺序:
-
- 如果返回值 小于 0,则将
a排在b前面。 - 如果返回值 等于 0,则
a和b的相对位置不变。 - 如果返回值 大于 0,则将
b排在a前面。
- 如果返回值 小于 0,则将
示例:数字升序排序
const arr = [10, 5, 20, 1];
arr.sort((a, b) => a - b);
console.log(arr); // 输出: [1, 5, 10, 20]
对对象数组排序
const users = [
{ name: 'Alice', age: 25 },
{ name: 'Bob', age: 30 },
{ name: 'Charlie', age: 20 },
];
users.sort((a, b) => a.age - b.age);
console.log(users);
// 输出:
// [
// { name: 'Charlie', age: 20 },
// { name: 'Alice', age: 25 },
// { name: 'Bob', age: 30 }
// ]
从 ES2019(ECMAScript 10)开始,sort 方法是 稳定排序 的。这意味着如果两个元素相等,它们的相对顺序在排序前后保持不变。
注意:sort 方法会直接修改原数组。如果需要保留原数组,可以先复制一份再排序
最终代码
const flattenArr = (arr: any[]): number[] => {
return arr.reduce((acc: number[], item) => {
// 如果当前元素是数组,递归拍平
if (Array.isArray(item)) {
acc.push(...flattenArr(item))
}else {
// 否则直接添加到结果数组
acc.push(item)
}
return acc
}, [])
}
const flattenAndSortArr = (arr: any[]): number[] => {
const flattenedArr = flattenArr(arr)
return flattenedArr.sort((a, b) => a - b)
}
const nestedArray = [1, 2, [4, 3], [[5, 6], 7]];
const flattenAndSortArrResult = flattenAndSortArr(nestedArray);
console.log(flattenAndSortArrResult);
扩展思考
上面的方法并没有考虑非数字元素,如果数组中有非数字元素会影响最终的排序结果
解决方法一:过滤非数字元素
function flattenArray(arr: any[]): number[] {
return arr.reduce((acc: number[], item) => {
if (Array.isArray(item)) {
acc.push(...flattenArray(item));
} else if (typeof item === 'number') {
//确保元素是数字元素才添加
acc.push(item);
}
return acc;
}, []);
}
解决方法二:自定义排序规则
function flattenAndSort(arr: any[], compareFn?: (a: number, b: number) => number): number[] {
const flattened = flattenArray(arr);
return flattened.sort(compareFn || ((a, b) => a - b));
}
至于这个排序规则函数就要根据实际情况自己来编写了