Php 按字母表排序,然后按数字排序拉威尔集合

Php 按字母表排序,然后按数字排序拉威尔集合,php,laravel,laravel-collection,Php,Laravel,Laravel Collection,我正在寻找一种方法来排序集合,这样名称从字母表开始,然后以数字开头。例如: $collection = collect([ ['name' => 'b', 'symbol' => '#'], ['name' => '2a', 'symbol' => '$'], ['name' => '1', 'symbol' => '@'], ['name' => 'a', 'symbol' => '%'] ]); 上述集合应按如

我正在寻找一种方法来排序集合,这样名称从字母表开始,然后以数字开头。例如:

$collection = collect([
    ['name' => 'b', 'symbol' => '#'],
    ['name' => '2a', 'symbol' => '$'],
    ['name' => '1', 'symbol' => '@'],
    ['name' => 'a', 'symbol' => '%']
]);
上述集合应按如下方式排序:

[
    [
        "name" => "a",
        "symbol" => "%",
    ],
    [
        "name" => "b",
        "symbol" => "#",
    ],
    [
        "name" => "1",
        "symbol" => "@",
    ],
    [
        "name" => "2a",
        "symbol" => "$",
    ],
]
但这是我使用
sortBy
方法对其排序时得到的结果:

$collection->sortBy('name')->values()->all();
[
    [
        "name" => "1",
        "symbol" => "@",
    ],
    [
        "name" => "2a",
        "symbol" => "$",
    ],
    [
        "name" => "a",
        "symbol" => "%",
    ],
    [
        "name" => "b",
        "symbol" => "#",
    ],
]

你知道如何对这个集合进行排序,使以字母开头的名字排在第一位吗。谢谢

您需要定义自己的自定义比较器函数,以便使用对这些集合对象进行排序

通过检查两个名称是否都是字母表来比较它们。如果两者都是字母表,则使用常用的字符串比较就足够了。如果其中任何一个是字母表,则通过返回值
-1
,将它们推到更高的等级,这意味着按排序顺序排列在上面。如果两者都是数字或字母数字,请再次使用


<?php

$collection = collect([
    ['name' => 'b', 'symbol' => '#'],
    ['name' => '2a', 'symbol' => '$'],
    ['name' => '1', 'symbol' => '@'],
    ['name' => 'a', 'symbol' => '%']
]);

$collection = $collection->sort(function($a,$b){
    $a_is_alphabet = preg_match('/^[a-zA-Z]+$/', $a['name']) === 1;
    $b_is_alphabet = preg_match('/^[a-zA-Z]+$/', $b['name']) === 1;

    if($a_is_alphabet && $b_is_alphabet){
        return strcasecmp($a['name'], $b['name']);
    }elseif($a_is_alphabet){
        return -1;
    }elseif($b_is_alphabet){
        return 1;
    }

    return strcasecmp($a['name'], $b['name']);
});