ReactJs - Organize your data with the sort method

In my React application, I have a table that fetches its data from an API.

I need to implement sorting for one of the columns. The values in this column are usually strings of numbers but sometimes can be equal to "-" (Dash).

Below is the sort function I am using:

if (order === "DEF") {
  const sorted = props.currency.sort((a, b) =>
    Number(a[obj1][obj2]) > Number(b[obj1][obj2])
      ? 1
      : Number(b[obj1][obj2]) > Number(a[obj1][obj2]) || a[obj1][obj2] === "-"
      ? -1
      : 0
  );
  props.setCurrency(sorted);
  setOrder("ASC");
} else if (order === "ASC") {
  const sorted = props.currency.sort((a, b) =>
    Number(a[obj1][obj2]) < Number(b[obj1][obj2]) || a[obj1][obj2] === "-"
      ? 1
      : Number(b[obj1][obj2]) < Number(a[obj1][obj2])
      ? -1
      : 0
  );
  props.setCurrency(sorted);
  setOrder("DSC");
} else {
  const sorted = defaultCurrency;
  props.setCurrency(sorted);
  setOrder("DEF");
}

After applying the sort, I want to treat "-" as zero. However, when the order is ASC or DSC, items with "-" should always appear at the top of the table, while the other array items are sorted correctly.

Answer №1

To treat "-" as a zero in the sorting function, you can include it as the first condition and return 0.

.sort((x, y) => {
    if (x[category][value] === "-") return 0;
    return Number(x[category][value]) > Number(y[category][value]) ? 1
     : Number(y[category][value]) > Number(x[category][value]) ? -1 : 0
})

Answer №2

To simplify this process, start by parsing the elements being compared and then implement a straightforward sorting logic.

Create a single function called customSort that takes an array, a function to extract the relevant property from each element, and a boolean for sorting direction (defaults to ascending: true).

The function extracts the value of each element using the provided function and converts it to a number using the unary plus operator (unary +).

Finally, sort the elements based on whether they are not-a-number or by subtracting based on the direction boolean.

const customSort = (arr, prop, asc = true) => {
  return [...arr].sort((a, b) => {
    a = +prop(a);
    b = +prop(b);

    return isNaN(a) - isNaN(b) || (asc ? a - b : b - a);
  })
}

const data = [{ prop1: { prop2: '2' } }, { prop1: { prop2: '5' } }, { prop1: { prop2: '3' } }, { prop1: { prop2: '1' } }, { prop1: { prop2: '-' } }, { prop1: { prop2: '9' } }, { prop1: { prop2: '-' } },];
const obj1 = 'prop1';
const obj2 = 'prop2';

console.log(customSort(data, (o) => o[obj1][obj2], true));
console.log(customSort(data, (o) => o[obj1][obj2], false));

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

Stop the click event using a confirmation dialog before proceeding with the operation

I'm trying to implement a confirmation dialog before deletion by using e.preventDefault() to prevent immediate deletion. However, I am facing an issue in the YES function where I would like to resume the click event's operation with return true w ...

Is it permissible to enclose useEffect hooks within an IIFE?

Currently, I am dealing with a project that is rife with anti-patterns. One issue that has caught my attention is the use of Immediately Invoked Function Expressions (IIFE) around multiple useEffect hooks. Here is a snippet of the code in question: conditi ...

I'm currently in the process of creating a snake game using HTML5. Can you help me identify any issues or problems that

I am experiencing an issue where nothing is appearing on the screen. Below are the contents of my index.html file: <html> <body> <canvas id="canvas" width="480" height="480" style="background-color:grey;"></canvas> <script src=" ...

Having difficulty loading the controller into my AngularJS module

I've been attempting to organize my angularjs controllers into separate files without success. Folder Structure: --public-- --js/controller/resturant.js --js/master.js --index.php Content of master.js angular.module("rsw",[ ...

What steps are involved in integrating Element Plus with Nuxt 3?

Seeking assistance with installing Element Plus in Nuxt 3. I followed the instructions from the official Element Plus documentation, but despite adding unplugin-vue-components, unplugin-auto-import, and adjusting webpack settings in the nuxt config file, ...

What is this error: "Unknown authentication strategy 'loca'"?

Whenever I try to utilize passport.js, it keeps throwing the following error: Unknown authentication strategy "local"! config/configuration.js var passport = require('passport') , LocalStrategy = require('passport-local').Strategy; ...

Using the outer ng-repeat's object property to filter nested ng-repeat items

I'm currently working on nesting two ng-repeats with two separate JSON files. The goal is to filter the second ng-repeat based on parameters from the first ng-repeat. The first JSON file, $scope.matches, includes information about each match in the W ...

Overlaying a div on top of an iframe

Struggling to make this work for a while now. It seems like a small issue related to CSS. The image isn't overlaying the IFrame at the top of the page as expected, it's going straight to the bottom. Here is the code snippet: .overlay{ width: ...

Error: Identifier Not Expected (Exploring Generators in ES6)

After delving into the information provided in the generators documentation on MDN, I devised a straightforward experiment: var nodes = { type: 'root', value: [ { type: 'char', value: 'a' }, { type: &ap ...

Emphasize specific lines within a textarea

I am facing a challenge with a textarea dedicated to validating telephone numbers. My goal is to highlight the lines that contain invalid telephone numbers by adding two asterisks in front of them. However, I'm struggling to figure out how to highlig ...

What is the best way to validate a particular class in javascript?

Need help checking if a specific id has a particular class. Unsure of the process? Here's the code snippet where the attempt at checking the id for a specific class is visible within the homeTransition function. function homeTransition() { ...

The material UI Paper component appears to be extending beyond the boundaries of the background image

I have configured the Grid component to occupy 6 on small/medium screens for a side-by-side layout and 12 on xs screens for each item. While everything looks fine in the computer view, I am facing an issue with the mobile view where the paper component is ...

Can you explain the meaning behind this TypeScript variable declaration syntax?

Can anyone explain the meaning of this code snippet: myCollection: Collection|any = null; I'm having trouble understanding it... Does it indicate that myCollection is set to type Collection, (which is an interface), with a default value of null? But ...

Having difficulty understanding why the Javascript regex is not functioning as expected

Can you help me validate user input to ensure it is a positive currency value in the correct format? Examples of valid formats include: 0.5, 0.55, 5 (please note this one), 5.5, 5.55, 55, etc. This is the code I am currently using: if ($("#gross").val() ...

Display information on a web page based on user input using HTML

I've hidden other p tags and divs using display:none, How can I make them visible after inputting my name? I'd like to type in my name and reveal all the content within the previously hidden div <form method="post"> <p> < ...

Error message: "Uncaught TypeError in NextJS caused by issues with UseStates and Array

For quite some time now, I've been facing an issue while attempting to map an array in my NextJS project. The particular error that keeps popping up is: ⨯ src\app\delivery\cart\page.tsx (30:9) @ map ⨯ TypeError: Cannot read pr ...

"How to prevent users from using the back button on Google Chrome and Edge browsers

window.history.pushState(null, null, location.href); window.addEventListener('popstate', () => { history.go(1); alert('The use of back button is restricted.'); }); An issue has been identified where the code snippet above d ...

Ways to transfer a value between two different card elements

I have designed a component with three div cards side by side using bootstrap. The first card displays a list of products, and my intention is that when a product is clicked, the details should appear in the second card on the same page. However, this fun ...

Show a modal when the axios request is finished

EDIT: After some exploration, I've shared the solution I found in case it helps others facing a similar issue. I'm currently working on building a reusable Bootstrap 5 modal child component within Vue3. The goal is to pass an ID as a prop from t ...

Node js Express js token authentication: unraveling the implementation complexities

After extensive research on authentication methods for nodejs and express js, I find myself at a crossroads. So far, the most helpful tutorial I've found on sessions is this one. I am working with the mean stack and my main goal is to provide users ...