1

I'm trying to sort rows of a table and change each column given the "sortBy" value in the state the state is dynamically changing but the function to sort isn't sorting the values properly . The function is currently sorting but its sorting the entire array instead of the selected sortBy value how do I fix this function so it sorts a single column rather then the entire array like its doing now

This is my state:

state = {
  columnHeaders: ["Meat", "Protein", "Calories", "Carbohydrates", "Fat"],
  rows: [
    ["chicken breast", "25", "200", "37", "8"],
    ["fried chicken", "45", "450", "21", "16"],
    ["baked fish", "15", "250", "30", "9"]
  ],
  sortedBy: "",
  order: "desc",
  query: "all"
};



const { columnHeaders, rows, query, sortedBy, order } = this.state;

const newRows = query === "all" 
  ? rows
  : rows.filter(row => row[0].includes(query));

const sortedRows = sortedBy === ""
  ? newRows
  : newRows.sort((a, b) => {
   const valueA = a[columnHeaders.indexOf(sortedBy)];
   const valueB = b[columnHeaders.indexOf(sortedBy)];
    let sortedValue = 0;
    if (valueA < valueB) {
      sortedValue = -1;
    } else if (valueA > valueB) {
      sortedValue = 1;
    }
    if (order === "desc") {
      // if descending order, turn around the sort order
      sortedValue *= -1;
    }
    return sortedValue;
  });

This is the map thats rendering the sortedRows variable

{
  sortedRows.map((row, i) => (
    <TableRow key={`thc-${i}`}>
      <TableItem row={row} />
    </TableRow>
  ));
}
2
  • "16" > "8" will be false, you need to convert into int by either parse or use + Commented Mar 6, 2019 at 6:29
  • parsing the sortedValue ? or the const valueA & valueB ? Commented Mar 6, 2019 at 6:32

1 Answer 1

1

You can check if the column is a numerical column or a string column using isNaN. If the column is a number, then simply subtract them. Else use localeCompare to sort the rows.

Also, I have added slice to copy the array since sort mutates the original array

const columnHeaders = ["Meat", "Protein", "Calories", "Carbohydrates", "Fat"];
const rows = [
    ["chicken breast", "25", "200", "37", "8"],
    ["fried chicken", "45", "450", "21", "16"],
    ["baked fish", "15", "250", "30", "9"]
  ];

const sortedBy = "Meat", order = "desc";

const newRows = rows.slice().sort((a, b) => {
  const valueA = a[columnHeaders.indexOf(sortedBy)];
  const valueB = b[columnHeaders.indexOf(sortedBy)];

  let sortedValue = 0;

  if (!isNaN(valueA) && !isNaN(valueB))
    sortedValue = valueA - valueB
  else
    sortedValue = valueA.localeCompare(valueB)

  if (order === "desc") {
    sortedValue *= -1;
  }
  return sortedValue;
})

console.log(newRows)

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

10 Comments

Implemented that but unfortunately its giving me the same result, its filter the entire row array instead of just one column
You want to sort only one column and keep the rest of columns in their previous position?
this is the link to the component: github.com/MateenCode/tablesort/blob/master/src/component/…, Yes just trying to sort one column based on the "sortBy" state which is dynamical changing with the onClick event
I don't understand what you're asking, sorry. Won't that show wrong nutrients for different meats?
Yes sorry I'm bit tired so I'm not doing the best job of exampling. I want this function to sort a single column that clicked the name of the column is being stored in a state called "sortBy" the function is currently sorting the entire rows array but I would like it to sort by the index that associated with the sortBy value for example if the sortBy : "Protein" I would like just the Protein column to sort rather then the whole thing
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.