Optimizing the sorting of object properties based on specific values (numbers or strings)

My goal is to simplify the process of sorting both number and string values. The first step involves checking if the parameter I've passed (which belongs to the DeliveryDetailsColumns constants) matches another parameter from a different type (ElectronicDeliveryType).

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

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

I'm currently working with an array of objects named filteredValues in pinia, which are of type ElectronicDeliveryType. My aim is to sort the selected column, but my current method is not very generic. I resort to a switch case that loops through all the options in DeliveryDetailsColumns. I am looking for a more generic solution that involves checking the names of each property in ElectronicDeliveryType against those in DeliveryDetailsColumns and verifying their types. What would be the best approach 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;
            [...]

Answer №1

Create a mapping of delivery details to their corresponding comparison function:

const compareFunctions = 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!)],
]);

You can then easily retrieve the comparison function from the map:

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

Ensure to validate if the specified column exists before using it:

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

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Ensuring the Presence of a Legitimate Instance in NestJS

I have been working on validating my request with the Product entity DTO. Everything seems to be in order, except for the 'From' and 'To' fields. The validation works correctly for the Customer and Type fields, but when incorrect data i ...

Converting an array of arguments into tuples within the range of <T extends Tuple> is denoted by [T, (...args: NonNullArray<T>) => any], where each tuple represents the argument of a

Let's start with a simple function that takes a tuple as its first argument and a function whose arguments are elements of the tuple that are not null as its second argument: let first: number | null | undefined; let last: number | null | undefined; l ...

Storing Angular header values in local storage

saveStudentDetails(values) { const studentData = {}; studentData['id'] = values.id; studentData['password'] = values.password; this.crudService.loginstudent(studentData).subscribe(result => { // Here should be the val ...

The value of Vue.js props appears as undefined

It appears that I may be misunderstanding how props work, as I am encountering difficulty passing a prop to a component and retrieving its value, since it always shows up as undefined. Route: { path: '/account/:username', name: 'accco ...

Sending an object to a Vue 2 component and confirming its validity

I am working with a Vue component that has numerous props. <Field v-for="field in fields" :key="field.name" :name="field.name" :type="field.type" :label="field.label" :values="field.values" :value ...

Unveiling the secrets of the Google Region Lookup API

I am struggling to incorporate the Region Area Lookup feature from Google Maps into my project. Despite it being an experimental feature, I am having difficulty getting it to function correctly. Initially, I attempted to integrate this feature into a Reac ...

Can we expect Karma to receive updates for upcoming versions of Angular and Jasmine?

We recently attempted to upgrade our company's Angular module, which required updating dependencies as well. Upon upgrading to the latest versions, we encountered an issue with the Jasmine-karma-HTML-Reporter due to its reliance on Jasmine-core 4.x.x ...

Resolving Cross-Origin Resource Sharing problem in Google authentication and authorization with React, Node.js, and Passport

I am currently experiencing the same issue as described in this Stack Overflow post. Unfortunately, I have been unable to implement @Yazmin's suggested solution successfully. My goal is to develop a stack using React, Express/Node.js, and MongoDB wit ...

What steps do I need to take to have the button conceal all unfinished tasks?

Here is the link to my Jsfiddle code snippet: https://jsfiddle.net/zxo35mts/1/ I am attempting to create a button that will hide all incomplete tasks when clicked, and then show them again when clicked again. However, I am struggling with figuring out how ...

The issue with the React Hook for window resize not updating remains unresolved

I have a React Hook designed to update the window size on resize, but it's not functioning correctly. Can someone please help explain why this is happening and provide guidance on how to utilize this hook in another component to create a Boolean value ...

Can you explain the distinction between using get() and valueChanges() in an Angular Firestore query?

Can someone help clarify the distinction between get() and valueChanges() when executing a query in Angular Firestore? Are there specific advantages or disadvantages to consider, such as differences in reads or costs? ...

What is the best way to send a value from a child component to a parent component using this.$emit

I am currently working on passing the const randomNumber from a child component [src/components/VueForm/FormQuestion.vue] to the parent component [src/App.vue]. I am using $emit to pass the data, but as a newcomer to this concept, I could use some guidance ...

Route user based on login status using router

I want to set up automatic routing to a login page for users who are not logged in. app.module.ts import { RouterModule, Routes } from '@angular/router'; import { AppComponent } from './app.component'; import { LoginComponent } from &ap ...

Is it possible in Angular to directly bind the emitted output of a component to a property?

My primary application component communicates with its sub components using @Output decorated properties on the subcomponent. The output properties utilize an EventEmitter<>(). Typically, these properties emit a simple boolean or number. I want to di ...

Mongoose and TypeScript - the _id being returned seems to be in an unfamiliar format

Experiencing unusual results when querying MongoDB (via Mongoose) from TypeScript. Defined the following two interfaces: import { Document, Types } from "mongoose"; export interface IModule extends Document { _id: Types.ObjectId; name: stri ...

What is the best way to display various tables depending on the grouping of a specific row value?

Recently, I came across some interesting JSON data that looks like this: [ { "fruit":"apple", "country": "A" }, { "fruit":"banana", "country": "b" }, { "fruit":&q ...

Obtaining data from a TypeScript decorator

export class UploadGreetingController { constructor( private greetingFacade: GreetingFacade, ) {} @UseInterceptors(FileInterceptor('file', { storage: diskStorage({ destination: (req: any, file, cb) => { if (process.env ...

Generate a dropdown menu with dynamic options populated from an API by adding an input type select element dynamically

Greetings! I am working on designing a decision tree that dynamically generates options based on user selections and API responses. When a user chooses a reason option, the corresponding reasons are fetched from the API and displayed in a select dropdown. ...

What is the best way to add query parameters to router.push without cluttering the URL?

In my current project, I am using NextJS 13 with TypeScript but not utilizing the app router. I am facing an issue while trying to pass data over router.push to a dynamically routed page in Next.js without compromising the clarity of the URL. router.push({ ...

Could you please install an older version of Vue.js devtools, or consider downloading an earlier release

Just noticed the latest update for vue devtools, but it seems to have some issues with displaying my vuex store data. The data gets updated after mutations but doesn't show up in the tool anymore. Has anyone figured out how to revert back to the prev ...