简体   繁体   English

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

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

I'm using a Laravel Collection and this is what I currently have. 我正在使用Laravel Collection,这是我目前拥有的。 I can sort by imageName or string length but I can't figure out how to do both at the same time. 我可以按imageName或字符串长度进行排序,但无法弄清楚如何同时执行这两种操作。 Some help would be appreciated! 一些帮助,将不胜感激!

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

@The Shift Exchange is right, natsort does that. natsort Exchange是正确的, natsort做到了。 However it only takes an array as argument. 但是,它仅将数组作为参数。 And it can't be a multilevel array. 而且它不能是多级数组。 array_multisort in combination with the SORT_NATURAL flag works much better. array_multisortSORT_NATURAL标志结合使用效果更好。

First we need to get a list. 首先,我们需要获取列表。 An array with only the property you want to sort by. 仅包含您要作为排序依据的属性的数组。 array_multisort will use this list to sort the full $items array. 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 uasort gets 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;
    });
}

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM