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);
posted @ 2018-07-16 21:52  DebraJohn  阅读(1461)  评论(0编辑  收藏  举报