0

I have an array of objects like this. I am trying to sort the array if the holidays have the same holiday_on, and Sort by holiday_for By Descending Order.

const holidays: IHoliday[] = [
    {
        id: 1,
        holiday_for: 1,
        holiday_on: "2021-10-26"
    },
    {
        id: 2,
        holiday_for: 3,
        holiday_on: "2021-10-26"
    },
    {
        id: 3,
        holiday_for: 1,
        holiday_on: "2021-11-26"
    },
    {
        id: 4,
        holiday_for: 3,
        holiday_on: "2021-11-26"
    },
    {
        id: 5,
        holiday_for: 4,
        holiday_on: "2021-11-26"
    }
]

With the implementation below getting this type error Argument of type '(a: IHoliday, b: IHoliday) => number | undefined' is not assignable to parameter of type '(a: IHoliday, b: IHoliday) => number'.Type 'number | undefined' is not assignable to type 'number'

If I make the holidays array any type then typescript giving another warning - Not all code paths return a value.

Implementation

const sorted = holidays.sort((a: IHoliday, b: IHoliday) => {
    if (a.holiday_on === b.holiday_on) {
        return b.holiday_for - a.holiday_for;
    }
});
2
  • 1
    Does this answer your question? Sort array of objects by string property value Commented Sep 17, 2021 at 3:04
  • I would suggest to use a library underscore or lodash both the libraries have lot of inbuilt utilities Commented Sep 17, 2021 at 4:55

2 Answers 2

1

I added another return so that if the holiday_on is not the same, it will sort the date but you cannot directly make an operation with the type Date in Typescript. Using getTime() method converts a Date into a number (Date.prototype.getTime()) so you can make the operation without error.

const sorted = this.holidays.sort((a: IHoliday, b: IHoliday) => {
  if (a.holiday_on === b.holiday_on) {
    return b.holiday_for - a.holiday_for;
  }
  return (
    new Date(b.holiday_on).getTime() - new Date(a.holiday_on).getTime()
  );
});
console.log(sorted);

I added a stackblitz for you to play on.

Sign up to request clarification or add additional context in comments.

Comments

0

Your sort function needs to always return a number. 0 if equal, >=1 if greater, and <=-1 if smaller.

const sorted = holidays.sort((a: IHoliday, b: IHoliday) => {
    if (a.holiday_on === b.holiday_on) {
        return b.holiday_for - a.holiday_for;
    }
    return new Date(b.holiday_on) - new Date(a.holiday_on)
});

This function will attempt to sort by holiday_on first, and only if it's equal, then it sorts by holiday_for.

2 Comments

In the second return where you have added new Date getting this error - The left-hand side of an arithmetic operation must be of type 'any', 'number', 'bigint' or an enum type.
Code should work if you ignore the error, but to be more specific you can use return new Date(b.holiday_on).getTime() - new Date(a.holiday_on).getTime()

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.