I need to sort a table that has columns of varying data types. The problem with sorting the strings is that they are case sensitive. The original code is
const Details = sortWith(
sortDir === 'ASC'
? ascend((row) => row.data[col])
: descend((row) => row.data[col])
)
and I updated it to the following which works
const Details = sortWith(
sortDir === 'ASC'
? ascend((row) => typeof row.data[col] === 'string' ? row.data[col].toLowerCase() : row.data[col])
: descend((row) => typeof row.data[col] === 'string' ? row.data[col].toLowerCase() : row.data[col])
)
Is there a better way to do this?
CodePudding user response:
If you want to avoid repeating yourself on the sorting you can isolate the typecheck function:
const stringCheck = (row) => typeof row.data[col] === 'string' ? row.data[col].toLowerCase() : row.data[col]
and then:
const Details = sortWith(
sortDir === 'ASC'
? ascend(stringCheck)
: descend(stringCheck)
)
CodePudding user response:
You can use the optional function call, it will be executed only if that method is defined for the type:
row.data[col].toLowerCase?.() ?? row.data[col]
The optional function call will return undefined whether the method is not defined, for this reason we need ?? row.data[col] in order to retrieve the previous value.
CodePudding user response:
Welcome to Stack Overflow. Please, in the future, try to post a Minimal Reproducible Example with your question.
I'm not sure whether this will help, but here is a configuration-based sorting function generator, built on Ramda's sorting capabilities:
const mySorter = (config) =>
sortWith (config .map (
({col, sortDir = 'ASC'}) => (sortDir == 'ASC' ? ascend : descend)
(pipe (path (['data', col]), when (is (String), toLower)))
))
const data = [{data: {first: 'Fred', last: 'Flintstone', age: 31}}, {data: {first: 'Wilma', last: 'Flintstone', age: 29}}, {data: {first: 'pebbles', last: 'flintstone', age: 1}}, {data: {first: 'Barney', last: 'Rubble', age: 29}}, {data: {first: 'bambam', last: 'Rubble', age: 1.5}}, {data: {first: 'Betty', last: 'Rubble', age: 33}}]
console .log (
mySorter ([{col: 'age'}, {col: 'last', sortDir: 'DESC'}]) (data)
)
console .log (mySorter ([{col: 'first'}]) (data))
.as-console-wrapper {max-height: 100% !important; top: 0}
<script src="//cdnjs.cloudflare.com/ajax/libs/ramda/0.28.0/ramda.min.js"></script>
<script>const {sortWith, ascend, descend, pipe, path, when, is, toLower} = R</script>
The part about lowercasing only the strings is when (is (String), toLower), which seems eminently readable.
