Home > OS >  Sort() function not working in TypeScript
Sort() function not working in TypeScript

Time:12-07

I have the following expression that aims to filter an array in the following sequential order:

  • filters the array using .includes searchTerm
  • sorts the results with those that start with the searchTerm appearing first by using startsWith
  • then sorts the results by having the shortest words appearing at the top, using .sort.

Expression:

let wordsFiltered = wordList
                    .filter(x =>shoetest.simplify(x).toLowerCase()
                            .includes(shoetest.simplify(searchTerm).toLowerCase()))
                    .sort((a, b) => b.startsWith(searchTerm) - a.startsWith(searchTerm))
                    .sort((a, b) => a.length - b.length);

2 errors:

  • The left-hand side of an arithmetic operation must be of type 'any', 'number', 'bigint' or an enum type.ts(2362)
  • The right-hand side of an arithmetic operation must be of type 'any', 'number', 'bigint' or an enum type.ts(2363)

I tried solutions I found online using valueOf(), toString(), and as string but they don't seem to work.

CodePudding user response:

Your sort function needs to return either a negative number to put a before b, a positive number to put b before a, or zero to leave as-is. .startsWith returns a boolean, so you're effectively doing something like true - false, which typescript doesn't like.

As such, it's easier to rewrite your last two sorts as this:

  .sort((a, b) => {
    if (a.startsWith(search) && !b.startsWith(search)) {
      return -1;
    } else if (!a.startsWith(search) && b.startsWith(search)) {
      return 1;
    } else {
      // Either both or neither start with search term, so sort by length.
      return a.length - b.length;
    }
  });

CodePudding user response:

You could convert the boolean to numbers by appending and then subtract them.

.sort((a, b) =>  b.startsWith(searchTerm) -  a.startsWith(searchTerm) )

There's another issue. You are chaining 2 sort calls. This will only use the second sort call while ignoring the first one. If you are trying to do a thenBy sort where if both the items startsWith the same searchTerm then use the shortest one first, you need to include that in the same sort using ||

// Declare it outside. No need to compute this in every call. 
let shoetestValue = shoetest.simplify(searchTerm).toLowerCase();

let wordsFiltered = wordList
  .filter(x => shoetest.simplify(x).toLowerCase().includes(shoetestValue))
  .sort((a, b) => 
         b.startsWith(searchTerm) -  a.startsWith(searchTerm) 
          || a.length - b.length
      )

Here's a snippet:

const searchTerm = "b";
const wordList = ["yellow", "black", "blue", "red"];

const wordsFiltered = wordList
  .sort((a, b) =>
     b.startsWith(searchTerm) -  a.startsWith(searchTerm) 
    || a.length - b.length
  )

console.log(wordsFiltered)

Typescript Payground with sample data

  • Related