简体   繁体   中英

Sort() function not working in TypeScript

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.

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;
    }
  });

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM