Как использовать _sortBy () от lodash для сортировки по списку в алфавитном порядке с пользовательскими требованиями? - PullRequest
0 голосов
/ 10 ноября 2018

У меня есть следующий массив объектов:

const myList = [
  { id: 1, title: '[A] Animal Bite - F - Not Pregnant' },
  { id: 2, title: '[P] Sinus Pain - M' },
  { id: 3, title: '[A] Animal Bite - F - Pregnant' },
  { id: 4, title: 'Check up male' },
  { id: 5, title: '[A] Animal Bite - M' },
  { id: 6, title: 'Duration' },
  { id: 7, title: '[P] Skin Injury - F - Not Pregnant' },
  { id: 8, title: '[P] Skin Injury - M' },
  { id: 9, title: 'Emergency Screening' }
]

После выполнения:

_.sortBy(myList, 'title');

Я получаю:

Check up male
Duration
Emergency Screening
[A] Animal Bite - F - Not Pregnant
[A] Animal Bite - F - Pregnant
[A] Animal Bite - M
[P] Sinus Pain - M
[P] Skin Injury - F - Not Pregnant
[P] Skin Injury - M

Это выглядит хорошо, за исключением того, что я хочу, чтобы элементы без [A] или [P] были внизу, а не сверху. Так вот так:

[A] Animal Bite - F - Not Pregnant
[A] Animal Bite - F - Pregnant
[A] Animal Bite - M
[P] Sinus Pain - M
[P] Skin Injury - F - Not Pregnant
[P] Skin Injury - M
Check up male
Duration
Emergency Screening

Как этого добиться?

Ответы [ 5 ]

0 голосов
/ 10 ноября 2018

Вы можете переместить части скобок вверх, проверив строки, а затем получить результат локального сравнения.

const
    startsWithBrackets = s => /^\[.+\]/.test(s),
    myList = [{ id: 1, title: '[A] Animal Bite - F - Not Pregnant' }, { id: 2, title: '[P] Sinus Pain - M' }, { id: 3, title: '[A] Animal Bite - F - Pregnant' }, { id: 4, title: 'Check up male' }, { id: 5, title: '[A] Animal Bite - M' }, { id: 6, title: 'Duration' }, { id: 7, title: '[P] Skin Injury - F - Not Pregnant' }, { id: 8, title: '[P] Skin Injury - M' }, { id: 9, title: 'Emergency Screening' }];

myList.sort(({ title: a }, { title: b }) =>
    startsWithBrackets(b) - startsWithBrackets(a) || a.localeCompare(b));

console.log(myList);
.as-console-wrapper { max-height: 100% !important; top: 0; }
0 голосов
/ 10 ноября 2018

Если вы действительно хотите использовать lodash, вы можете сравнить заголовки в нижнем регистре:

_.sortBy(myList, item => item.title.toLowerCase());

Это работает, потому что единица кода символов нижнего регистра (97 - 122) больше, чем единица кода [ (91). Это также поможет сравнить заголовки без учета регистра.

0 голосов
/ 10 ноября 2018

Используйте localeCompare с параметром numeric: false в функции сортировки:

const list = [ { id: 1, title: '[A] Animal Bite - F - Not Pregnant' }, { id: 2, title: '[P] Sinus Pain - M' }, { id: 3, title: '[A] Animal Bite - F - Pregnant' }, { id: 4, title: 'Check up male' }, { id: 5, title: '[A] Animal Bite - M' }, { id: 6, title: 'Duration' }, { id: 7, title: '[P] Skin Injury - F - Not Pregnant' }, { id: 8, title: '[P] Skin Injury - M' }, { id: 9, title: 'Emergency Screening' } ] 

const r = list.sort((a,b) => a.title.localeCompare(b.title, 0, {numeric: false}))

console.log(r)

Другой способ получить тот же результат - через параметр опции {caseFirst: lower'}, как отмечено (и объяснено) с помощью @xehpuk asnwer:

const list = [ { id: 1, title: '[A] Animal Bite - F - Not Pregnant' }, { id: 2, title: '[P] Sinus Pain - M' }, { id: 3, title: '[A] Animal Bite - F - Pregnant' }, { id: 4, title: 'Check up male' }, { id: 5, title: '[A] Animal Bite - M' }, { id: 6, title: 'Duration' }, { id: 7, title: '[P] Skin Injury - F - Not Pregnant' }, { id: 8, title: '[P] Skin Injury - M' }, { id: 9, title: 'Emergency Screening' } ] 

const r = list.sort((a,b) => a.title.localeCompare(b.title, 0, {caseFirst: 'lower'}))

console.log(r)

Вам также не нужен lodash для этого, если ES6 является опцией.

0 голосов
/ 10 ноября 2018

Лодаша sortBy может занять список компараторов. Таким образом, вы можете просто объявить «слова не начинаются с квадратной скобки иди позже» и внутри «группы» сортировать по заголовку

_.sortBy(myList, [
    item => !item.title.startsWith("["), 
    'title'
]);

И с помощью orderBy вы даже можете указать порядок более читабельным (и гибким) способом:

_.orderBy(myList, [
    item => item.title.startsWith("["), 
    'title'
], ['desc', 'asc']);

[UPD] с startsWith, упомянутым @Ele, выглядит еще лучше

0 голосов
/ 10 ноября 2018

Это альтернатива с использованием функции Array.prototype.sort()

Предполагается, что в строке есть максимум один [.

const myList = [  { id: 1, title: '[A] Animal Bite - F - Not Pregnant' },  { id: 2, title: '[P] Sinus Pain - M' },  { id: 3, title: '[A] Animal Bite - F - Pregnant' },  { id: 4, title: 'Check up male' },  { id: 5, title: '[A] Animal Bite - M' },  { id: 6, title: 'Duration' },  { id: 7, title: '[P] Skin Injury - F - Not Pregnant' },  { id: 8, title: '[P] Skin Injury - M' },  { id: 9, title: 'Emergency Screening' }];

myList.sort((a, b) => {
  if (a.title.startsWith("[") && b.title.startsWith("[")) {
    return a.title.substring(1).localeCompare(b.title.substring(1)); 
  } 
  
  return a.title.localeCompare(b.title);
});

console.log(myList);
.as-console-wrapper { max-height: 100% !important; top: 0; }
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...