Я заказываю массив с помощью lodash / orderBy. Я не могу контролировать, что возвращается в массив. Когда в элементах моего массива есть новые строки, они не упорядочиваются так, как я ожидал. Есть ли способ игнорировать новые строки? Или каким-либо другим способом правильно оформить заказ?

const shouldBeFirst = 'My message\r\n\r\nshould consist of A A A A some 
text';
const shouldBeSecond= 'My message\r\n\r\nshould consist of \r\n\r\n some 
text';

const array = [
 { text: 'xxx' },
 { text: shouldBeFirst },
 { text: 'yyy' },
 { text: shouldBeSecond},
 { text: 'zzz' }];

const ordered = orderBy(array, ['day'], ['asc']);

Я ожидаю получить эти предметы в следующем порядке:

 { text: shouldBeFirst },
 { text: shouldBeSecond},
 { text: 'xxx' },
 { text: 'yyy' },
 { text: 'zzz' }];

Однако порядок, в котором я их помещаю, следующий:

 { text: shouldBeSecond },
 { text: shouldBeFirst },,
 { text: 'xxx' },
 { text: 'yyy' },
 { text: 'zzz' }];

[изменить: на самом деле мне нужно отсортировать по большему количеству полей, поэтому фактическая сортировка будет больше похожа на код ниже]

 const array = [
 { text: 'xxx', day: 'monday', hour: '12' },
 { text: shouldBeFirst, day: 'tuesday', hour: '12' },
 { text: 'yyy', day: 'wednesday', hour: '12' },
 { text: shouldBeSecond, day: 'thursday', hour: '12'},
 { text: 'zzz', day: 'friday', hour: '12' }];

const ordered = orderBy(array, ['day', 'hour', 'text'], ['asc', 'asc', 'asc']);
0
rozza 19 Сен 2018 в 17:27

2 ответа

Лучший ответ

РЕДАКТИРОВАТЬ: ПЕРЕСМОТРЕЛ МОЙ ОТВЕТ - действительно можно использовать orderBy

Да, вы можете сделать это с помощью orderBy, предоставив функцию для сравнение .

const shouldBeFirst = 'My message\r\n\r\nshould consist of A A A A some text';
const shouldBeSecond= 'My message\r\n\r\nshould consist of \r\n\r\n some text';

const array = [
 { text: 'xxx' },
 { text: shouldBeFirst },
 { text: 'yyy' },
 { text: shouldBeSecond},
 { text: 'zzz' }];

const ordered = _.orderBy(array, item => item.text.replace(/\s+/g, " "));

console.log(ordered)
<script src="https://cdn.jsdelivr.net/npm/lodash@4.17.11/lodash.min.js"></script>

При необходимости замену можно отрегулировать - это просто для иллюстрации того, как ее можно определить. Несколько критериев по-прежнему можно передавать в виде массива

const shouldBeFirst = 'My message\r\n\r\nshould consist of A A A A some text';
const shouldBeSecond= 'My message\r\n\r\nshould consist of \r\n\r\n some text';

const array = [
 { text: 'xxx', value: 2 },
 { text: 'xxx', value: 1 },
 { text: shouldBeFirst },
 { text: 'yyy', value: 42 },
 { text: 'yyy', value: 12 },
 { text: shouldBeSecond},
 { text: 'zzz', value: 7 }];

//separating criteria for better readability
const criteria1 = item => item.text.replace(/\s+/g, " ");
const criteria2 = 'value'; //you can still pick by property name

//order by sanitized values of the text property first, followed by the value property
const ordered = _.orderBy(array, [criteria1, criteria2]);

console.log(ordered);
<script src="https://cdn.jsdelivr.net/npm/lodash@4.17.11/lodash.min.js"></script>
1
VLAZ 20 Сен 2018 в 08:17

Вместо этого используйте _.sortBy. Вы можете сопоставить значения перед заказом:

const ordered = _.sortBy(array, arrayItem => arrayItem.text.replace(/\W+/g, " "));

Это /\W+/g является регулярным выражением, которое удаляет все не буквенно-цифровые символы из элемента массива перед его сравнением.

И, если вы хотите отсортировать по нескольким значениям:

const ordered = _(array).chain()
                        .sortBy(arrayItem => arrayItem.day)
                        .sortBy(arrayItem => arrayItem.hour)
                        .sortBy(arrayItem => arrayItem.text.replace(/\W+/g, " "))
                        .value();

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

1
André-Jacques de Beer 19 Сен 2018 в 15:13