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 usingstartsWith
- 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)