3

I want to use pipe to sort names ending with numbers.

I have used custom pipe and getting results as expected

  • $Apple fruit -symbol
  • 1Apple fruit -numbers
  • Apple fruit -alphabetically

But it is not sorting if name ends with number.

Result now:

  • Apple fruit3
  • Apple fruit01
  • Apple fruit5
  • Apple fruit02

JSON

[
{"name": "Apple fruit3"},
{"name": "$Apple fruit"},
{"name": "Apple fruit"},
{"name": "Apple fruit01"},
{"name": "Apple fruit5"},
{"name": "Apple fruit02"},
]

HTML

<div *ngFor='let list of names | appOrderBy : "name" '>
<div>{{list.name}}</div>
</div>

OrderBy Custom Pipe

import { Pipe, PipeTransform } from '@angular/core';
@Pipe({
     name: 'appOrderBy'
})
export class OrderBy implements PipeTransform {
transform(array: Array<string>, args: string): Array<string>{
array.sort((a: any, b: any) => {
  if (a[args] < b[args]) {
    return -1;
  } else if (a[args] > b[args]) {
    return 1;
  } else {
    return 0;
  }
});
return array;
}
}
Jesse W
  • 91
  • 1
  • 8
  • 1
    Doesn't work?? https://stackblitz.com/edit/angular-pipe-to-sort?file=src%2Fapp%2Fapp.component.ts – Ashish Ranjan Oct 19 '18 at 04:31
  • Thanks @AshishRanjan . This method worked too but i will keep Adrain Brand changes for now which looks more simple and meaningful to me – Jesse W Oct 19 '18 at 14:46
  • I had meant that your code was already working for me... removing the `else` part will not cause any visible change, even if you will add the else it will still be the same.. – Ashish Ranjan Oct 19 '18 at 15:02
  • Consider avoid using an order by pipe and instead filtering in the component only as needed. [No FilterPipe or OrderByPipe](https://angular.io/guide/pipes#appendix-no-filterpipe-or-orderbypipe) – Alexander Staroselsky Oct 19 '18 at 21:50

1 Answers1

2

Use an Intl.Collator as your compare function for natural number sorting.

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Collator

const array = [
  {name: "Apple fruit3"},
  {name: "$Apple fruit"},
  {name: "Apple fruit"},
  {name: "Apple fruit01"},
  {name: "Apple fruit5"},
  {name: "Apple fruit02"},
];

args= 'name';

var collator = new Intl.Collator(undefined, {numeric: true, sensitivity: 'base'});

array.sort((a, b) => collator.compare(a[args], b[args]));

console.log(array);

I based this answer off searching for a natural number sort Google search which returned this post.

Javascript : natural sort of alphanumerical strings

Adrian Brand
  • 20,384
  • 4
  • 39
  • 60