Maurizio Rizzo
Maurizio Rizzo

Reputation: 837

Sort an array of objects in typescript?

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!

Upvotes: 76

Views: 188258

Answers (13)

Jay Dee
Jay Dee

Reputation: 2646

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'));

Upvotes: 0

Lijo Vijayan
Lijo Vijayan

Reputation: 85

consider your array as myArray,

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

Upvotes: -3

Syed Faran Raza
Syed Faran Raza

Reputation: 39

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 )

Upvotes: 2

Petebr
Petebr

Reputation: 155

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
     });

Upvotes: 2

Zymka
Zymka

Reputation: 141

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

Upvotes: 7

Yoannes Geissler
Yoannes Geissler

Reputation: 841

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;
})

Upvotes: 0

jbdeguzman
jbdeguzman

Reputation: 1124

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));

Upvotes: 86

Aswathi Chandran
Aswathi Chandran

Reputation: 31

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)
}

Upvotes: 0

Mohammad
Mohammad

Reputation: 971

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;
})

Upvotes: 1

[{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;
});

Upvotes: 6

rlloyd2001
rlloyd2001

Reputation: 321

    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;
    });

Upvotes: 21

coenni
coenni

Reputation: 422

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?

Upvotes: 6

Jaroslaw K.
Jaroslaw K.

Reputation: 5374

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;
});

Upvotes: 57

Related Questions