Explanation: Since you asked for a description, I'm trying my best to explain it as simple as possible first: The sort
function you apply to an array generally expects two arguments to be compared directly and returns a number. This number can be seen as "smaller than" (negative), "greater than" (positive) or "equals" (zero). Therefore, the function will be called multiple times in your case. In theory, it's also possible to not have these two arguments, e.g. for a random order you could write: cars.sort(() => Math.random() - 0.5)
So, any function that returns a number can be used in order to sort an array. In your case it would be:
Sorting by defined hierachy of categories / use ID in case of same category:
const cars: { id: number; category: string }[] = [ { id: 3, category: "fast car" }, { id: 0, category: "fast car" }, { id: 1, category: "slow car" }, { id: 2, category: "fast car" } ]; const orderCategory = { 'fast car': 1, 'slow car': 2 }; cars.sort((carA, carB) => { if (carA.category !== carB.category) { return orderCategory[carA.category] - orderCategory[carB.category]; } else { return carA.id - carB.id; } }); console.log(cars);
Two other advices:
- You can use
const
instead of let
in your case - You do not have to use quotation marks for
id
and category
I hope my explanation could help you! Happy coding
EDIT: Formatted code.
EDIT 2: I just saw that you wanted fast cars to be listed at first. In my previous implementation, this worked because of the alphabetical order (F < S). But if the alphabetical order is not the reason why you want them to be listed at first, you'll have to define categories. You could now rename "fast car" to "sports car" (everywhere) and the respective cars would be listed at first, whereas they would have been below each "slow car" based on the alphabetical sorting.
I just updated the code above. This is the old implementation based on the alphabetical order:
Alphabetical sorting of categories / use ID in case of same category:
cars.sort((carA, carB) => { if (carA.category < carB.category) { return -1; } else if (carA.category > carB.category) { return 1; } // same as: else if (carA.category === carB.category) else { return carA.id - carB.id; } });
EDIT 3: Adjusted random sorting example in my explanation. Math.random() returns a number between 0 and 1. Thus, I substracted 0.5 in order to randomly return a negative number.