如何按字符串长度和字母顺序对 Laravel Collection 进行排序?
How can I sort a Laravel Collection by both string length and alphabetically?
我正在使用 Laravel Collection,这就是我目前拥有的。我可以按 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
你所追求的是自然排序。 PHP does provide this functionality,因此您只需要将其合并到您的函数中即可。
我还没有尝试过 - 但按照这些思路应该可行(或者至少为您指明了正确的方向):
function sortCards($collection) {
return $collection->sortBy(function($collection) {
return natsort($collection->imageName);
})
编辑:这甚至可能有效:
function sortCards($collection) {
return natsort($collection->imageName);
}
@Shift Exchange 是正确的,natsort
does that. However it only takes an array as argument. And it can't be a multilevel array. 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;
});
}
我正在使用 Laravel Collection,这就是我目前拥有的。我可以按 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
你所追求的是自然排序。 PHP does provide this functionality,因此您只需要将其合并到您的函数中即可。
我还没有尝试过 - 但按照这些思路应该可行(或者至少为您指明了正确的方向):
function sortCards($collection) {
return $collection->sortBy(function($collection) {
return natsort($collection->imageName);
})
编辑:这甚至可能有效:
function sortCards($collection) {
return natsort($collection->imageName);
}
@Shift Exchange 是正确的,natsort
does that. However it only takes an array as argument. And it can't be a multilevel array. 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;
});
}