Как отсортировать коллекцию Laravel по длине строки и по алфавиту?

Я использую коллекцию Laravel, и это то, что у меня сейчас есть. Я могу сортировать по imageName или длине строки, но я не могу понять, как сделать оба одновременно. Некоторая помощь будет оценена!

function sortCards($collection) {
return $collection->sortBy(function($key) {
return strlen($key->imageName);
})
->values();
}

Я тоже попробовал это:

function sortCards($collection) {
return $collection->sortBy(function($key) {
return $key->imageName;
})
->sortBy(function($key) {
return strlen($key->imageName);
})
->values();
}

Когда я делаю это таким образом, он сортирует только по последнему методу сортировки, поэтому он сортируется по алфавиту.

Например, если имена изображений:

p1, p1a, p2, p2a, p3, p3a, p4, p4a

Ожидаемые результаты будут:

p1, p2, p3, p4, p1a, p2a, p3a, p4a

0

Решение

@ Обмен смены прав, natsort делает это Однако он принимает только массив в качестве аргумента. И это не может быть многоуровневый массив. array_multisort в сочетании с SORT_NATURAL флаг работает намного лучше.

Сначала нам нужно получить список. Массив только с тем свойством, по которому вы хотите отсортировать. array_multisort будет использовать этот список для сортировки полной $items массив.

function sortCards($collection){
$items = $collection->all();
$list = $collection->lists('imageName');

array_multisort($list, SORT_ASC, SORT_NATURAL, $items);

return new Collection(array_values($items));;
}

редактировать

Поскольку естественная сортировка в PHP отдает приоритет алфавитному порядку по длине, и вам нужно наоборот, вы должны сделать это самостоятельно, используя sort() (под капотом uasort вызывается)

function sortCards($collection){
return $collection->sort(function($a, $b){
$lengthA = strlen($a->imageName);
$lengthB = strlen($b->imageName);
$valueA = $a->imageName;
$valueB = $b->imageName;

if($lengthA == $lengthB){
if($valueA == $valueB) return 0;
return $valueA > $valueB ? 1 : -1;
}
return $lengthA > $lengthB ? 1 : -1;
});
}
3

Другие решения

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

Я не пробовал — но что-то в этом роде должно работать (или, по крайней мере, указывать вам правильное направление):

function sortCards($collection) {
return $collection->sortBy(function($collection) {
return natsort($collection->imageName);
})

редактировать: это может даже работать:

  function sortCards($collection) {
return natsort($collection->imageName);
}
0