makeSorter
I'm always confusing myself when writing sort functions, so I wrote makeSorter(). It's
insanely simple and just works™. It makes writing an array sort callback for anything
other than an array of numbers or strings easier.
import { select, option, div, span, ul, li } from 'tosijs'.elements
import { icons, makeSorter } from 'tosijs-ui'
const people = [
{ first: 'Frasier', last: 'Crane', age: 38 },
{ first: 'Lilith', last: 'Crane', age: 37 },
{ first: 'Rebecca', last: 'Howe', age: 35 },
{ first: 'Woody', last: 'Boyd', age: 25 },
{ first: 'Sam', last: 'Malone', age: 40 },
{ first: 'Norm', last: 'Peterson', age: 38 },
]
const sorters = {
firstSort: makeSorter(person => [person.first]),
firstDescSort: makeSorter(person => [person.first], false),
nameSort: makeSorter(person => [person.last, person.first]),
ageFirst: makeSorter(person => [-person.age, person.last]),
ageLast: makeSorter(person => [person.age, person.first], [true, false]),
}
function person({first, last, age}) {
return li(`${first} ${last}, ${age}`)
}
const list = ul()
sortPicker = select(
option('Sort by first', {value: 'firstSort'}),
option('Sort by first (desc)', {value: 'firstDescSort'}),
option('Sort by last, first', {value: 'nameSort'}),
option('Sort by age (desc), first', {value: 'ageFirst'}),
option('Sort by age, last (desc)', {value: 'ageLast'}),
{
onChange: render,
value: 'nameSort'
},
)
function render () {
list.textContent = ''
list.append(...people.sort(sorters[sortPicker.value]).map(person))
}
preview.append(
div(
sortPicker,
icons.chevronDown()
),
list
)
render()
.preview {
padding: var(--spacing);
}
.preview div {
position: absolute;
top: var(--spacing);
right: var(--spacing);
}
Details
To create a sort callback that sorts by propA then propB (if propA is tied):
const sorter = makeSorter(
obj => [obj.propA, obj.propB]
)
As above, but sort descending:
const sorter = makeSorter(
obj => [obj.propA, obj.propB],
false
)
As above but propA is sorted ascending, propB descending
const sorter = makeSorter(
obj => [obj.propA, obj.propB],
[true, false]
)