【问题标题】:How can I sort a Laravel Collection by both string length and alphabetically?如何按字符串长度和字母顺序对 Laravel 集合进行排序?
【发布时间】:2015-03-01 07:18:03
【问题描述】:

我正在使用 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

【问题讨论】:

    标签: php sorting laravel collections


    【解决方案1】:

    你所追求的被称为自然排序。 PHP does provide this functionality,所以你只需要将它合并到你的函数中。

    我还没有尝试过 - 但是按照这些思路应该可以工作(或者至少为您指明正确的方向):

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

    编辑:这甚至可以工作:

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

    【讨论】:

    • 第一个给我错误:natsort() 期望参数 1 是数组,给定字符串。第二个不行。抱歉,我的问题中有错别字,我已修复。
    • 我试过了,返回 natsort($collection);但它说集合是一个对象。
    【解决方案2】:

    @Shift Exchange 是对的,natsort 做到了。但是它只需要一个数组作为参数。而且它不能是多级数组。 array_multisortSORT_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;
        });
    }
    

    【讨论】:

    • 我试过了,但仍然没有正确排序。我希望它先按 imageName 字符串长度排序,然后按字母顺序排序。例如,如果图像名称是 p1、p1a、p2、p2a、p3、p3a、p4、p4a,我希望它排序为 -> p1、p2、p3、p4、p1a、p2a、p3a、p4a。跨度>
    • 啊,所以长度应该是第一优先,字母顺序是第二。认为您将需要手动执行此操作。我看看我能不能想出点什么来。
    • 好的,我已经用“手动”排序的代码更新了问题。看看吧。
    猜你喜欢
    • 1970-01-01
    • 2021-04-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-12-19
    • 2011-03-30
    • 2013-09-04
    • 1970-01-01
    相关资源
    最近更新 更多