Search code examples
typescriptdatesortingluxon

Sort by multiple field typescript


I'm trying to sort on multiple fields but I can't do it

My array:

details = [
{
  dateDebut: '2014-10-10',
  rank:1
},
{
  dateDebut: '2020-12-12',
  rank:0
},
{
  dateDebut: '2014-10-10',
  rank:0
},
{
  dateDebut: '2014-10-10',
  rank:2
},
{
  dateDebut: '2020-11-11',
  rank:1
},
{
  dateDebut: '2020-11-11',
  rank:0
}
]

I would like to sort by decreasing date and by decreasing rank to get the following result:

 details = [
    {
      dateDebut: '2020-12-12',
      rank:0
    },
    {
      dateDebut: '2020-11-11',
      rank:1
    },
    {
      dateDebut: '2020-11-11',
      rank:0
    },
    {
      dateDebut: '2014-10-10',
      rank:2
    },
    {
      dateDebut: '2014-10-10',
      rank:1
    },
    ,
    {
      dateDebut: '2014-10-10',
      rank:0
    },
]

On my project, for the dates, Luxon is used. I did the following treatment but I don't get the right result ...:

component.ts :

details.sort((d1, d2) => this.myService.sortByRangAndDates(d1, d2, 'desc'));

service.ts :

sortByRangAndDates(d1: Details, d2: Details, order: 'asc' | 'desc'): number {
    const orderValue = order === 'desc' ? -1 : 1;

    const convert = (s: string): number => {
      return s ? new Date(s).getUTCDate() : 0;
    };


    return (convert(d1?.dateDebut) < convert(d2?.dateDebut)) || (d1.rank < d2.rank ) ? orderValue :
      (convert(d1?.dateDebut) > convert(d2?.dateDebut)) || (d1.rank > d2.rank ) ? -1 * orderValue : 0;

  }

Can you help me please ? :)

Thank you


Solution

  • Fixed your code a bit, and created 2 sorting functions. First by date and then if the date is the same, sort by rank.

    type Details = {
      dateDebut: string;
      rank: number;
    };
    const convert = (s: string): number => s ? new Date(s).getTime() : 0
    
    const sortByDate = (d1: Details, d2: Details, order: string): number =>
      order == "asc"
        ? convert(d1.dateDebut) > convert(d2.dateDebut)
          ? 1
          : -1
        : convert(d1.dateDebut) > convert(d2.dateDebut)
        ? -1
        : 1;
    
    const sortByRange = (d1: Details, d2: Details, order: "asc" | "desc"): number =>
      d1.dateDebut == d2.dateDebut
        ? order == "asc"
          ? d1.rank > d2.rank
            ? 1
            : -1
          : d1.rank > d2.rank
          ? -1
          : 1
        : 0;
    details.sort((d1, d2) => sortByDate(d1, d2, "desc"));
    details.sort((d1, d2) => sortByRange(d1, d2, "desc"));
    
    console.log(details);
    

    TS play link: https://tsplay.dev/WzLKQN