Search code examples
typescriptvue.jspinia

Sort by specific object property value (number, string) optimization


I want to simplify a method of sorting number and string values, where first, I check if my passed parameter (which is of type DeliveryDetailsColumns contants) is the same string as the one parameter of another type (EletronicDeliveryType)

export const DeliveryDetailsColumns = {
  Title: "title",
  ExpectedDelivery: "expectedDelivery",
  Price: "price",
  Quantity: "quantity",
};

export interface ElectronicDeliveryType {
  title?: string;
  quantity?: number;
  price?: number;
  expectedDelivery?: string;
}

I have the array of objects in pinia of name filteredValues, type of ElectronicDeliveryType. I want to sort selected column, for now I have not so generic method where I do a switch case through all of the DeliveryDetailsColumns options and I would like to make it generic with the names of ElectronicDeliveryType - DeliveryDetailsColumns check and check of the types of property, what can be the solution here?

 sortBySelectedColumnOrder(columnName: string, sortOrder: string) {
      if (sortOrder === "ascending") {
        switch (columnName) {
          case DeliveryDetailsColumns.Title:
            this.filteredValues.sort((a, b) =>
              a!.title!.toLowerCase() > b!.title!.toLowerCase() ? 1 : -1
            );
            break;
          case DeliveryDetailsColumns.Price:
            this.filteredValues.sort((a, b) => a!.price! - b!.price!);
            break;
            [...]

Solution

  • Make a map of delivery details to their respective comparator function:

    const comparators = new Map<
        keyof typeof DeliveryDetailsColumns,
        (a: ElectronicDeliveryType, b: ElectronicDeliveryType) => number
    >([
        [DeliveryDetailsColumns.Title, (a, b) => a!.title!.toLowerCase() > b!.title!.toLowerCase() ? 1 : -1],   
        [DeliveryDetailsColumns.Price, (a, b) => a!.price! - b!.price!)],
    ]);
    

    Then you can just do a lookup on the map:

    this.filteredValues.sort(comparators.get(columnName)!);
    

    But make sure to check if the column exists first:

    if (!comparators.has(columnName)) { ... }