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

时间:2015-01-03 01:51:20

标签: php sorting laravel collections

我使用的是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

2 个答案:

答案 0 :(得分:3)

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

答案 1 :(得分:0)

你所追求的被称为自然类型。 PHP does provide this functionality,因此您只需将其纳入您的功能。

我没有尝试过 - 但沿着这些方面应该有用(或者至少指出你正确的方向):

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

编辑:这甚至可能有效:

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