ts-多属性排序
现在有一个学生数组:
enum Sex {
man,
woman
}
interface Student {
Name: string,
Age: number,
Sex: Sex
}
const Students: Student[] = [
{ Name: 'lux', Age: 18, Sex: Sex.man },
{ Name: 'hey', Age: 21, Sex: Sex.man },
{ Name: 'haha', Age: 23, Sex: Sex.woman },
{ Name: 'yo', Age: 19, Sex: Sex.woman }
]
需要按照年龄(或其他属性)来排序。
在上上篇笔记里面,提到了阮一峰的快速排序:
var arr = [6,2,5,1,3];
function quickSort(arr:Number[]):Number[]{
if(arr.length <= 1){
return arr;
}
var pivotIndex = Math.floor(arr.length/2);
var pivot = arr.splice(pivotIndex,1)[0];
var left = [] as Number[];
var right = [] as Number[];
for(var i =0;i<arr.length;i++){
if (arr[i] < pivot) {
left.push(arr[i]);
} else {
right.push(arr[i]);
}
}
return quickSort(left).concat([pivot], quickSort(right));
}
console.log(quickSort(arr));
那么,对于学生数组的排序,也是基于这个快排的方法。
首先,我们需要给函数签名添加一个参数,用来传递学生数组的属性。
function orderby<Titem, Tvalue>(arr: Titem[], selector: (i: Titem) => Tvalue): Titem[]
(其中用到了泛型的概念)
参数arr代表我们需要传入的学生数组,而selector代表学生数组中具体的某一个属性。
接下来这一段就是快速排序的源代码:
if (arr.length <= 1) {
return arr;
}//如果数组的项小于等于1,直接返回数组就OK
const pivotIndex = Math.floor(arr.length / 2);//取中间的索引
const pivot = arr.splice(pivotIndex, 1)[0];//取中间的学生
const left = [] as Titem[];
const right = [] as Titem[];
接下来的这一段,用来做排序的判断。
for (const i of arr) {
if (selector(i) < selector(pivot)) {
left.push(i);
} else {
right.push(i);
}
}
return orderby(left, selector).concat([pivot], orderby(right, selector));
调用的方法:
const StudentOrderbyAge = orderby(Students, i => i.Age);
console.log(StudentOrderbyAge);
源码:
function orderby<Titem, Tvalue>(arr: Titem[], selector: (i: Titem) => Tvalue): Titem[] {
if (arr.length <= 1) {
return arr;
}
const pivotIndex = Math.floor(arr.length / 2);
const pivot = arr.splice(pivotIndex, 1)[0];
const left = [] as Titem[];
const right = [] as Titem[];
for (const i of arr) {
if (selector(i) < selector(pivot)) {
left.push(i);
} else {
right.push(i);
}
}
return orderby(left, selector).concat([pivot], orderby(right, selector));
}
const StudentOrderbyAge = orderby(Students, i => i.Age);
console.log(StudentOrderbyAge);
JS源码:
function orderby(arr, selector) {
if (arr.length <= 1) {
return arr;
}
const pivotIndex = Math.floor(arr.length / 2);
const pivot = arr.splice(pivotIndex, 1)[0];
const left = [];
const right = [];
for (const i of arr) {
if (selector(i) < selector(pivot)) {
left.push(i);
} else {
right.push(i);
}
}
return orderby(left, selector).concat([pivot], orderby(right, selector));
}
const StudentOrderbyAge = orderby(Students, i => i.Age);
console.log(StudentOrderbyAge);