76

How do I sort an array of objects in TypeScript?

Specifically, sort the array objects on one specific attribute, in this case nome ("name") or cognome ("surname")?

/* Object Class*/
export class Test{
     nome:String;
     cognome:String;
}

/* Generic Component.ts*/
tests:Test[];
test1:Test;
test2:Test;

this.test1.nome='Andrea';
this.test2.nome='Marizo';
this.test1.cognome='Rossi';
this.test2.cognome='Verdi';

this.tests.push(this.test2);
this.tests.push(this.test1);

thx!

1
  • 4
    What have you tried? Please show the code that you've tried, and we can suggest how to fix it. Commented Apr 9, 2017 at 19:47

13 Answers 13

86

Simplest way for me is this:

Ascending:

arrayOfObjects.sort((a, b) => (a.propertyToSortBy < b.propertyToSortBy ? -1 : 1));

Descending:

arrayOfObjects.sort((a, b) => (a.propertyToSortBy > b.propertyToSortBy ? -1 : 1));

In your case, Ascending:

testsSortedByNome = tests.sort((a, b) => (a.nome < b.nome ? -1 : 1));
testsSortedByCognome = tests.sort((a, b) => (a.cognome < b.cognome ? -1 : 1));

Descending:

testsSortedByNome = tests.sort((a, b) => (a.nome > b.nome ? -1 : 1));
testsSortedByCognome = tests.sort((a, b) => (a.cognome > b.cognome ? -1 : 1));
Sign up to request clarification or add additional context in comments.

4 Comments

Hi, can we use a parameter while specifying the name of the prameter? like you have done a.name, can we do a.(some parameter which has the prop name)?
One of the greatest answers I've ever read here. Worked like a charm!!!
where are the types as in typescript?
Yes @Timo this would work in ts
57

It depends on what you want to sort. You have standard sort funtion for Arrays in JavaScript and you can write complex conditions dedicated for your objects. f.e

var sortedArray: Test[] = unsortedArray.sort((obj1, obj2) => {
    if (obj1.cognome > obj2.cognome) {
        return 1;
    }

    if (obj1.cognome < obj2.cognome) {
        return -1;
    }

    return 0;
});

3 Comments

this is just a small example, my array is composed of not less than 20 elements
I guess that you do not understand function passed as argument of sort method. The function always has two arguments (the same type what objects in your array) and it shows how to sort your array. In my example, size of array does not matter. Array may has two or one thousand elements. Sorting will be by comparison element by function (obj1, obj2) => { //..comparing } every time
You can also use localeCompare instead of the multiple ifs: (obj1, obj2) => obj1.cognome.localeCompare(obj2.cognome)
21
    const sorted = unsortedArray.sort((t1, t2) => {
      const name1 = t1.name.toLowerCase();
      const name2 = t2.name.toLowerCase();
      if (name1 > name2) { return 1; }
      if (name1 < name2) { return -1; }
      return 0;
    });

Comments

7

You could use a function with a generic type:

const sortArrayOfObjects = <T>(
  data: T[],
  keyToSort: keyof T,
  direction: 'ascending' | 'descending' | 'none',
) => {
  if (direction === 'none') {
    return data
  }
  const compare = (objectA: T, objectB: T) => {
    const valueA = objectA[keyToSort]
    const valueB = objectB[keyToSort]

    if (valueA === valueB) {
      return 0
    }

    if (valueA > valueB) {
      return direction === 'ascending' ? 1 : -1
    } else {
      return direction === 'ascending' ? -1 : 1
    }
  }

  return data.slice().sort(compare)
}

Now if you use the function to sort array of objects, you can specify the object attribute you want to sort by.

const array = [
  { id: 2, name: "name2" },
  { id: 1, name: "name1" },
  { id: 3, name: "name3" }
];

const sortedArray = sortArrayOfObjects(array, "id", "ascending")

console.log(sortedArray)
//sorted ascending by id
// [
//   { id: 1, name: "name1" },
//   { id: 2, name: "name2" },
//   { id: 3, name: "name3" }
// ]

Using generic type and 'keyOf T' as type of attribute helps us to select only available object attributes, in this case, "id" and "name". typescript helper

CodeSandbox example

Comments

6
this.tests.sort(t1,t2)=>(t1:Test,t2:Test) => {
    if (t1.nome > t2.nome) {
        return 1;
    }

    if (t1.nome < t2.nome) {
        return -1;
    }

    return 0;
}

have you tried sth like this?

2 Comments

how to implement something as generic as the size of my array varies periodically?
it sorts all list, if list size changes, sorted array size will change as well
6
[{nome:'abc'}, {nome:'stu'}, {nome:'cde'}].sort(function(a, b) {
  if (a.nome < b.nome)
    return -1;
  if (a.nome > b.nome)
    return 1;
  return 0;
});

Comments

2

I often need to sort on a single field in a data set result, say Id and the shortest way of writing that is this

data.sort((a, b) => a.Id - b.Id)
    .forEach(row => {
           //something with row
     });

Comments

2
var arr = [110,5,72,14,12]

Ascending Order Sort

arr.sort(( a, b ) => a > b ? 1 : -1 )

Descending Order Sort

arr.sort(( a, b ) => a < b ? 1 : -1 )

Comments

1

you can use this method.

let sortedArray: Array<ModelItem>;
sortedArray = unsortedArray.slice(0);
sortedArray.sort((left, right) => {
    if (left.id < right.id) return -1;
    if (left.id > right.id) return 1;
    return 0;
})

Comments

0

I am using angular 7 and I tried pipe but didn't work and I tried this and got the output right.

let array of objects be in object result

results:any ={
 "providers": [
  {
    "name": "AAA",
    "error": {
      "success": true,
      "message": "completed"
    },
    "quote_id": "BA503452VPC0012790",
    "quotes": {
      "comprehensive": {
        "premiumBreakup": {
          "premium": "17398.0",
        }
      },
    }
  },
  {
    "name": "Fi",

    "error": {
      "success": true,
      "message": "completed"
    },
    "quotes": {
      "comprehensive": {
        "premiumBreakup": {
          "premium": "27957.00"              
        }
      },
    }
  },
]
}

On clicking sort function

<button class="t-sort-optn" (click)="sortByPremium()">Premium</button>

To sort based on the premium value

sortByPremium(){
    var items = this.results.providers;
    console.log("Array",items);
    items.sort(function (a, b) {
    return a.quotes.comprehensive.premiumBreakup.premium - b.quotes.comprehensive.premiumBreakup.premium;
    });
    console.log("Array Sorted",items)
}

Comments

0

This is how it worked for me

.sort((a, b) => {
  const a2 = a as unknown as Type;
  const b2 = b as unknown as Type;
  if (a2.something > b2.something) {
    return 1;
  }
  
  if (a2.something < b2.something) {
    return -1;
  } 

  return 0;
})

Comments

0

To make it more both readable and reusable, we have created a helper function:

export const by = <T>(attribute: keyof T) => {
  return (one: T, two: T) => {
    if (one[attribute] < two[attribute]) {
      return -1;
    } else if (one[attribute] > two[attribute]) {
      return 1;
    } else {
      return 0;
    }
  };
};

Then we can use it like this:

const users = [ /* items here */ ];
const sorted = users.sort(by('name'));

Comments

-3

consider your array as myArray,

myArray.sort(( a, b ) => a > b ? 1 : -1 )

1 Comment

This should have been myArray.sort(( a, b ) => a > b ? 1 : -1 )

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.