73

I'm trying to sort a string[] in descending way. So far what I have done is the code below:

let values = ["Saab", "Volvo", "BMW"]; // example 

values.sort();
values.reverse();

It's working but I'm trying to figure out if there is a better way to do it.

4
  • 2
    A better way? Better how? What problem are you trying to solve? Commented Nov 7, 2016 at 18:59
  • 21
    values.sort((a,b) => 0 - (a > b ? 1 : -1));? Commented Nov 7, 2016 at 19:02
  • 2
    Like haim said, provide a comparison function (check out the array sort docs developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/…). You would do the sort and provide a comparison function, perhaps you could also take advantage of the string localCompare (developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/…) Commented Nov 7, 2016 at 19:07
  • @haim770 great! Commented Nov 7, 2016 at 19:15

5 Answers 5

117

You need to create a comparison function and pass it as a parameter of sort function:

values.sort((one, two) => (one > two ? -1 : 1));
Sign up to request clarification or add additional context in comments.

4 Comments

Does this hack consider the case in array of strings?
@Memmo I'm not sure what your asking. It will compare the character values one by one. Uppercase will sort ahead of lower case.
I understand. I'm looking for a way to sort them in the same way as the lowercase ones. So that there is no case difference.
Call uppercase() on both of them before the comparison.
86

A more current answer is that you can utilize String.prototype.localCompare() to get a numeric comparison value.

Simple example:

let values = ["Saab", "Volvo", "BMW"];
values.sort((a, b) => b.localeCompare(a))

This also won't cause TypeScript warnings as the output of localCompare is a number.

More info and additional function parameters can be seen here: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/localeCompare

4 Comments

this won't work with ['9', '75', '72', '64', '61', '60', '6', '59', '57', '56', '54', '53', '52', '5', '47', '46', '44', '42', '41', '40', '4', '3', '26', '25', '22', '21', '20', '2', '19', '17', '16', '14', '13', '12']
@VirajSingh to sort numeric string values you will need to use values.sort((a, b) => b.localeCompare(a, undefined, {numeric: true}))
This is a more elegant solution than a.toUpperCase() > b.toUpperCase() ? -1 : 1, but be careful with very large datasets, localeCompare is about twice slower, even though it still is pretty quick.
I think this is the only answer that considers TypeScript, which was part of the original question.
14

Use the following code to sorting the Array in ascending and descending order.

const ascending: any= values.sort((a,b) =>  (a > b ? 1 : -1));
const descending: any= values.sort((a,b) => (a > b ? -1 : 1))

Comments

0

The most recent lib that I know

https://www.npmjs.com/package/ngx-pipes

const numbers = [2, 1, 3];
 
const obj = [
  {id: 4, name: 'Dave', amount: 2},
  {id: 2, name: 'Michael', amount: 2},
  {id: 3, name: 'Dan', amount: 1},
  {id: 1, name: 'John', amount: 1}
];
 
const deepObj = [
  {id: 1, name: 'John', amount: 1337, deep: {prop: 4}},
  {id: 2, name: 'Michael', amount: 42, deep: {prop: 2}},
  {id: 3, name: 'Dan', amount: 1, deep: {prop: 1}},
  {id: 4, name: 'Dave', amount: 2, deep: {prop: 3}}
];

<!-- Returns array ordered by value -->
<p>{{ numbers | orderBy }}</p>  <!-- Output: [1, 2, 3] -->
<p>{{ numbers | orderBy: '-' }}</p>  <!-- Output: [3, 2, 1] -->
 
<!-- Returns array ordered by value of property -->
<p>{{ deepObj | orderBy: 'amount' }}</p>  
<!-- Output: [{id: 3, ...}, {id: 4, ...}, {id: 2, ...}, {id: 1, ...}] -->
<p>{{ deepObj | orderBy: '-amount' }}</p>  
<!-- Output: [{id: 1, ...}, {id: 2, ...}, {id: 4, ...}, {id: 3, ...}] -->
 
<!-- Returns array ordered by value of deep property -->
<p>{{ deepObj | orderBy: 'deep.prop' }}</p>  
<!-- Output: [{id: 3, ...}, {id: 2, ...}, {id: 4, ...}, {id: 1, ...}] -->
<p>{{ deepObj | orderBy: '-deep.prop' }}</p>  
<!-- Output: [{id: 1, ...}, {id: 4, ...}, {id: 2, ...}, {id: 3, ...}] -->
 
<!-- Returns array ordered by mutliple properties -->
<p>{{ obj | orderBy: ['amount', 'id'] }}</p>  
<!-- Output: [{id: 1, ...}, {id: 3, ...}, {id: 2, ...}, {id: 4, ...}] -->

Must be like this programmatically

@Component({
  // ..
  providers: [OrderByPipe]
})
export class AppComponent {
  constructor(private orderByPipe: OrderByPipe){
     let values = ["Saab", "Volvo", "BMW"];
     this.orderByPipe.transform(values, '-');
  }
}

Comments

0

This is normal reverse sorting

var nums:number[] = [1,2,3,4]
nums.sort((a,b)=> a < b ? 1:-1)
[ 4, 3, 2, 1 ]

If you have to do the sorting of custom objects, try this

class Student{
    name:String
    marks:Number
    constructor(name:string, marks:number) {
        this.name = name
        this.marks = marks
    }
}

var students:Array<Student> = [
    new Student("aseem",47),
    new Student("prem",97),
    new Student("john",100)

]

console.log(students.sort( (a,b)=> a.marks > b.marks ? -1:1 ))

would result in sorting by marks in reverse order

/usr/local/bin/node /Users/asee2278/git/mycode/JavaScriptLab/typeScript/concepts/sort.js
[
  Student { name: 'john', marks: 100 },
  Student { name: 'prem', marks: 97 },
  Student { name: 'aseem', marks: 47 }
]

1 Comment

The community encourages adding explanations alongisde code, rather than purely code-based answers (see here).

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.