сортировка по нескольким столбцам по убыванию

151

Есть отличный метод для сортировки массива объектов на основе нескольких свойств:

var data = _.sortBy(array_of_objects, ['type', 'name']);

Однако это только для сортировки по возрастанию. Есть ли какой-нибудь удобный способ определения направления для каждого столбца? Например

var data = _.sortBy(array_of_objects, [{'type': 'asc'}, {'name': 'desc'}]);
nhaa123
источник

Ответы:

330

Начиная с lodash 3.5.0 вы можете использовать sortByOrder (переименован в orderBy в v4.3.0):

var data = _.sortByOrder(array_of_objects, ['type','name'], [true, false]);

Начиная с версии 3.10.0 вы даже можете использовать стандартную семантику для упорядочивания (asc, desc):

var data = _.sortByOrder(array_of_objects, ['type','name'], ['asc', 'desc']);

В версии 4 lodash этот метод был переименован в orderBy :

var data = _.orderBy(array_of_objects, ['type','name'], ['asc', 'desc']);
djskinner
источник
7
Для вашей информации, эта функция была переименована в _.orderBy ( lodash.com/docs#orderBy ) в Lodash с 4.3.0. Нормальная функция сортировки называется _.sortBy ( lodash.com/docs#sortBy )
Нидин Дэвид
2
Я получаю _.sortByOrder is not a functionв последней версии Lodash.
Чови
66
Почему lodash продолжает переименовывать функции?
Кенни Уорден
13
Эта , ['asc', 'desc']часть просто игнорируется для меня с lodash@4.17.10. Все просто отсортировано по возрастанию.
Манинак
4
@maninak Это для _.sortBy. Попробуй _.orderByвместо этого. Надеюсь это поможет.
pcasme
45

Вы всегда можете использовать Array.prototype.reverse()

var data = _.sortBy(array_of_objects, ['type', 'name']).reverse();
RomanMinkin
источник
Ха, это умно. для числовой сортировки по возрастанию (по умолчанию lodash по убыванию) я использовал это: _.sortBy (array_of_objects, "some_numeric_value_key"). reverse ()
devonj
3
Хотя этого достаточно для некоторых случаев, эффект этого заключается в сортировке по убыванию по ОБА столбцам, а это не то, что задает вопрос.
Inkling
Пожалуйста, предложите ответ? stackoverflow.com/questions/62611489/…
regg garav
14

Стоит отметить, что если вы хотите отсортировать определенные свойства по убыванию, вы не хотите просто добавлять .reverse () в конце, так как это приведет к сортировке всех сортировок по убыванию.

Чтобы сделать определенные сортировки по убыванию, объедините их в цепочку от наименее значимых до наиболее значимых, вызывая .reverse () после каждой сортировки, которую вы хотите убывать.

var data = _(data).chain()
    .sort("date")
    .reverse()    // sort by date descending
    .sort("name") // sort by name ascending
    .result()

Поскольку сортировка _ является стабильной сортировкой, вы можете безопасно сортировать цепочки и выполнять обратную сортировку, потому что если два элемента имеют одинаковое значение для свойства, их порядок сохраняется.

Больше информации

каракатица
источник
Если у вас недостаточно представителей, чтобы комментировать, не комментируйте. Хотя вы изложили это в фактическом ответе, и это хорошо, но вам даже не нужно упоминать этот факт.
ArtOfCode
Пожалуйста, предложите ответ? stackoverflow.com/questions/62611489/…
regg garav
13

Глубокое поле и многополюсное расположение в разных направлениях Lodash> 4

var sortedArray = _.orderBy(mixedArray,
                            ['foo','foo.bar','bar.foo.bar'],               
                            ['desc','asc','desc']);
Месут Йигит
источник
На самом деле это будет ответом сейчас. sortBy не дает вам указания, а orderBy делает.
Пабло Паласиос
Пожалуйста, предложите ответ? stackoverflow.com/questions/62611489/…
regg garav
5

Есть ли какой-нибудь удобный способ определения направления для каждого столбца?

Нет. Вы не можете указать порядок сортировки, кроме как с помощью функции обратного вызова, которая инвертирует значение. Даже это не возможно для сортировки по нескольким столбцам.

Вы могли бы сделать

 _.each(array_of_objects, function(o) {
     o.typeDesc = -o.type; // assuming a number
 });
 _.sortBy(array_of_objects, ['typeDesc', 'name'])

Для всего остального вам нужно прибегнуть к нативной функции .sort()с пользовательской функцией сравнения:

 array_of_objects.sort(function(a, b) {
     return a.type - b.type // asc
         || +(b.name>a.name)||-(a.name>b.name) // desc
         || …;
 });
Берги
источник
3

В документации версии 4.11.x говорится: `" Этот метод похож на _.sortBy, за исключением того, что он позволяет указывать порядки сортировки для итераторов для сортировки. Если порядки не указаны, все значения сортируются в порядке возрастания. В противном случае укажите порядок «desc» для убывания или «asc» для возрастания порядка сортировки соответствующих значений. » (источник https://lodash.com/docs/4.17.10#orderBy )

let sorted = _.orderBy(this.items, ['fieldFoo', 'fieldBar'], ['asc', 'desc'])

Алехандро Силва
источник
Я думаю, что вы хотели использовать _.sortByOrder?
AJ Richardson
не могу найти переменную _
Вишал Вагасия
Пожалуйста, предложите ответ? stackoverflow.com/questions/62611489/…
regg garav
0

Вы также можете попробовать это:

var data= _.reverse(_.sortBy(res.locals.subscriptionList.items, ['type', 'name']));
Шубхам Верма
источник
Это будет намного медленнее, чем просто использование _.orderBy
reggaeguitar