微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

按字母排序,然后按数字排序 Laravel 集合

如何解决按字母排序,然后按数字排序 Laravel 集合

我正在寻找一种对集合进行排序的方法,即以字母开头的名称位于顶部,然后以数字开头的名称。例如:

$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",[
        "name" => "a",]

任何想法如何对这个集合进行排序,以便以字母开头的名称排在第一位。谢谢

解决方法

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

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

<?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']);
});

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。