如何按字符串长度和字母顺序对 Laravel 集合进行排序?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/27750956/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-14 10:38:06  来源:igfitidea点击:

How can I sort a Laravel Collection by both string length and alphabetically?

phpsortinglaravelcollections

提问by rotaercz

I'm using a Laravel Collection and this is what I currently have. I can sort by imageName or string length but I can't figure out how to do both at the same time. Some help would be appreciated!

我正在使用 Laravel Collection,这就是我目前拥有的。我可以按 imageName 或字符串长度排序,但我无法弄清楚如何同时进行。一些帮助将不胜感激!

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

I've tried this too:

我也试过这个:

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

When I do it this way it only sorts based on the last sorting method, so it is alphabetically unsorted.

当我这样做时,它仅根据最后一种排序方法进行排序,因此它是按字母顺序未排序的。

For example if the image names are:

例如,如果图像名称是:

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

Expected results would be:

预期结果是:

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

回答by lukasgeiter

@The Shift Exchange is right, natsortdoes that. However it only takes an array as argument. And it can't be a multilevel array. array_multisortin combination with the SORT_NATURALflag works much better.

@Shift Exchange 是对的,natsort确实如此。但是它只需要一个数组作为参数。它不能是多级数组。array_multisortSORT_NATURAL标志结合使用效果更好。

First we need to get a list. An array with only the property you want to sort by. array_multisortwill use this list to sort the full $itemsarray.

首先我们需要得到一个列表。一个只包含您想要排序的属性的数组。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));;
}

Edit

编辑

Since PHP's natural sort prioritizes the alphabetical order over the length and you need the opposite you have to do it yourself using sort()(under the hood uasortgets called)

由于 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;
    });
}

回答by Laurence

What you are after is referred to as a natural sort. PHP does provide this functionality, so you'll just need to incorporate it into your function.

你所追求的被称为自然排序。PHP 确实提供了此功能,因此您只需要将其合并到您的函数中。

I havent tried it - but something along these lines should work (or at least point you in the right direction):

我还没有尝试过 - 但是沿着这些方向的东西应该可以工作(或者至少指向正确的方向):

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

edit: this might even work:

编辑:这甚至可能有效:

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