Comments 21
Пример с C++ поправьте, функция должна быть аналогична C-шной, а не через || (сравнение id только при равенстве salary).
В силу того, что у вас есть sort() принимающий функцию компаратор, думаю не так сложно сделать что-то похожее на компаратор из джавы.
Не хотелось бы вас расстраивать, но..
const compare_string = ( left, right )=>
( left < right ) ? -1
: ( left > right ) ? 1
: 0
const compare_numb = ( left, right )=>
left - right
const compare_field = ( field, compare )=>
( left, right )=>
compare( left[ field ], right[ field ] )
const compare_combine = ( ... comparators )=>
( left, right )=> {
for( const compare of comparators ) {
const res = compare( left, right )
if( res ) return res
}
return 0
}
const compare_reverse = ( compare )=>
( left, right )=> compare( right, left )
const compare_user = compare_combine(
compare_field( 'salary', compare_reverse( compare_numb ) ),
compare_field( 'name', new Intl.Collator().compare ),
compare_field( 'id', compare_string ),
)
items.sort( compare_user )
Вот и вся библиотека, которая ещё и быстрее работать будет. Заодно компаратор можно не только для сортировки использовать, но и, например, для бинарного поиска по отсортированному массиву.
Спасибо, такой подход это один из вариантов который я рассматривал, и правда можно довольно выразительно это сделать.
Но есть несколько замечаний:
- сравнение чисел через
compare_numb
можно делать черезcompare_string
и не обрабатываетNaN
. - использование строк как ключей объектов не позволяет использовать TypeScript и более сложные выражения
- я намеренно стремлюсь использовать сортировку именно по ключу, потому что это более очевидно для использования
- бинарный поиск так же можно использовать, имея функцию ключа
конечно, умение правильно сортировать на ЯП это большой плюс к уровню прогера.
Вот к такому нужно стремиться.очень верно подмечено
К сожалению, SQL это отдельный язык и без специального синтаксиса нет возможности внедрить это напрямую.это одно из звеньев и двухзвенной и трёхзвенной архитектур, и плохо что это не рассматривается на том же уровне, что и остальные части.
Если единственная проблема с lodash была в неудобном интерфейсе - почему бы просто не обернуть его в удобный?
Там проблемы не только в самом интерфейсе, но и в строгости. Этот функционал в lodash просто отсуствует.
Даже если вопрос был исключительно в удобности интерфейса, написать с нуля будет проще, чем писать такой адаптер.
Вот в статье вы пишете:
поскольку направление сортировки указывается отдельно от самого критерия, не очевидно в какую сторону он будет сортироваться
Больше я претензий не заметил, а для конкретно этой проблемы адаптер пишется в один вызов (пример на Typescript, на чистом джиесе будет еще короче):
// тип дескриптора
type SortDescriptor<T> = {
prop: keyof T,
desc?: boolean
}
// определение
function sort<T>(source: T[], ...orders: SortDescritor<T>[]): T[] {
return _.orderBy(
source,
orders.map(x => x.prop),
orders.map(x => x.desc ? 'desc' : 'asc')
);
}
// пример вызова
const result = sort(myData, { prop: 'foo' }, { prop: 'bar', desc: true });
[ответ не туда]
Дисклеймер: я — один из авторов.
Нельзя ребят оставлять на легаси проектах, просто звереют от скуки.
А как насчёт варианта из Ramda?
Решаем вопрос сортировки в JavaScript раз и навсегда