Angular pipe sorting

2019-08-17 18:44发布

问题:

According to this question -> Ascending and Descending Sort in Angular 4

I've made the same pipe, but it can't sort numbers naturally. I mean 2 is > then 11.

How can this pipe be modified to sort both string and numbers?

@Pipe({
    name: 'orderBy'
})

export class OrderByPipe implements PipeTransform {

    transform(records: Array<any>, args?: any): any {
        if (records && records.length > 0) {
            return records.sort(function (a, b) {                 
                if (a[args.property] < b[args.property]) {
                    return -1 * args.direction;
                } else if (a[args.property] > b[args.property]) {
                    return 1 * args.direction;
                } else {
                    return 0;
                }
            });

        }
    }
}

回答1:

That's because you are sorting the values as strings - lexicographically. The input for your pipe seems to be of type Array<{ [propertyName: string]: [value: string] }>.

Either make sure that the input property values are numbers or convert the values to number before comparing.

In case you need to sort based on the type of the data that came to your pipe, you can use something like this:

@Pipe({
  name: 'orderBy'
})
export class OrderByPipe implements PipeTransform {

  transform(records: Array<any>, args?: any): any {
    if (records && records.length > 0) {
      return records.sort(
        (a, b) => args.direction * (
          typeof a[args.property] === 'number'
            ? (a[args.property] - b[args.property])
            : a[args.property] > b[args.property] ? 1 : -1)
      );
    }
  }
}

Hope this helps a little :-)