Pull to refresh

Comments 21

Пример с C++ поправьте, функция должна быть аналогична C-шной, а не через || (сравнение id только при равенстве salary).

Большое спасибо, исправлено!

В силу того, что у вас есть sort() принимающий функцию компаратор, думаю не так сложно сделать что-то похожее на компаратор из джавы.

Совершенно верно, и библиотека thenby использует именно этот подход.

Не хотелось бы вас расстраивать, но..


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 и более сложные выражения
  • я намеренно стремлюсь использовать сортировку именно по ключу, потому что это более очевидно для использования
  • бинарный поиск так же можно использовать, имея функцию ключа
  1. Не прикапывайтесь к примеру.) Впрочем, compare_numb быстрее, чем compare_string.
  2. Тайпскриптом всё чудесно типизируется. Компаратор по выражениям пишется аналогично.
  3. Компаратор позволяет не вычислять ключ полностью, когда это не нужно.
Stable sort давно в стандарте языка. По факту, сейчас его нет только в IE для массивов больше 512 элементов.
это всё хорошо, пока у вас минимум данных, а вот когда их много — все ваши варианты идут лесом. и останется только сортировка совмещённая с выборкой в субд.
конечно, умение правильно сортировать на ЯП это большой плюс к уровню прогера.

Вот к такому нужно стремиться.
очень верно подмечено
К сожалению, 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 });

А, я подумал что написать адаптер который позволит вызывать как моем финальном варианте.
Да, тот вариант что вы предлагаете действительно прост в исполнении, но все равно я предпочту свой интерфейс. (плюс я не доволен кодом и сложностью lodash)

AlaSQL.js была специально разработана для использования синтаксиса SQL при сортировках в JavaScript.

Дисклеймер: я — один из авторов.

Справедливости ради, эта библиотека решает больше вопросов чем просто сортировка :)

Нельзя ребят оставлять на легаси проектах, просто звереют от скуки.

Sign up to leave a comment.

Articles