Laravel/PHP:按字母顺序排序并按数字顺序排序

14

按字母顺序排序后,我得到了这个:

S1 Episode 1
S1 Episode 11
S1 Episode 12
S1 Episode 2
S1 Episode 3

S2 Episode 1
S2 Episode 11

示例代码:

DB::table('test')->orderby('title', 'ASC')->get();

等等,我需要这些正确排序。有什么解决方案吗?

谢谢。

8个回答

22
你面临的问题是对项目进行字母数字排序,或者用计算机科学的术语来说,是进行自然排序。许多方法可以使用纯粹的MySQL实现自然排序,但你也可以将Laravel助手的结果转换为数组格式,并使用PHP的natsort函数进行实现。
从我找到的方法中,我推导出了最好的方式,很可能可以通过以下示例代码解决你的问题:
DB::table('test')->orderBy('LENGTH(title)', 'ASC')
    ->orderBy('title', 'ASC')
    ->get();

然而,我不确定助手是否会抱怨在orderBy函数中接收到一个MySQL函数而不是一个直接的列名。我只是根据我使用的参考资料和你的示例进行转录 - 我不能保证效果。

8
这对我有用,但我必须使用orderByRaw(LENGTH(field),'ASC')。非常感谢,这是一个直观的解决方案。 - Noel Murphy

10

对于一些人来说可能有点晚了,但对其他人可能会有所帮助。

根据上述链接,我找到了下面的内容,并据此推导出最佳解决方法,该方法很可能可以通过示例代码解决您的问题: https://www.electrictoolbox.com/mysql-order-string-as-int/

查询

SELECT * FROM <table> ORDER BY CAST(<column> AS unsigned)

laravel实例

DB::table('test')
    ->orderByRaw("CAST(title as UNSIGNED) ASC")
    ->get();

5
对于Laravel,这也可以运行:
$collection = $collection->sortBy('order', SORT_REGULAR, true);

请注意,SORT_REGULAR是PHP常量,而不是Laravel指令。这里是PHP参考资料,以及其他用于排序的常量,例如SORT_NATURAL、SORT_NUMERIC等:https://www.php.net/manual/en/array.constants.php - Genki

4
DB::table('test')->orderByRaw('LENGTH(title)', 'ASC')
->orderBy('title', 'ASC')
->get();

3
请始终将您的答案放在上下文中,而不仅仅是粘贴代码。有关详细信息,请参见此处 - gehbiszumeis
你很聪明! - Daniyal Javani

0

对于 Laravel 集合:

$collection = collect([
    ['sn' => '2'],
    ['sn' => 'B'],
    ['sn' => '1'],
    ['sn' => '10'],
    ['sn' => 'A'],
    ['sn' => '13'],
]);

$sorted = $collection->sortBy('sn');

$sorted = $collection->sortBy('sn');

//print_r($collection);

Illuminate\Support\Collection Object
(
    [items:protected] => Array
        (
            [2] => Array
                (
                    [sn] => 1
                )

            [0] => Array
                (
                    [sn] => 2
                )

            [3] => Array
                (
                    [sn] => 10
                )

            [5] => Array
                (
                    [sn] => 13
                )

            [4] => Array
                (
                    [sn] => A
                )

            [1] => Array
                (
                    [sn] => B
                )

        )

)

正如你所见,这将正确排序。然而,如果你想对其进行排序和重新索引,则:

$sorted = $collection->sortBy('sn')->values()->all();

//print_r($sorted)

Array
(
    [0] => Array
        (
            [sn] => 1
        )

    [1] => Array
        (
            [sn] => 2
        )

    [2] => Array
        (
            [sn] => 10
        )

    [3] => Array
        (
            [sn] => 13
        )

    [4] => Array
        (
            [sn] => A
        )

    [5] => Array
        (
            [sn] => B
        )

)

此外,您还可以传递自己的回调函数来确定如何对集合值进行排序。
$sorted = $collection->sortBy(function ($item, $key) {
    //your logic
});

更多详情请参见:https://laravel.com/docs/5.8/collections#method-sortby


0

基本上和被接受的答案一样,但是去掉了逗号并使用orderByRaw。否则会出现关于绑定的错误。

DB::table('test')->orderByRaw('LENGTH(title) ASC')->orderBy('title', 'ASC')->get();


大家好,有人可以确认一下上面的代码有什么问题吗?(这样我就不会再犯同样的错误了)谢谢。 - MandyF
不确定,但我觉得看起来不错。 - C.Astraea

-1

使用eloquent,这对我很有效,非常简单:

Eloquent

$tests = Test::all();
$tests = $tests->sortBy('title', SORT_REGULAR, false); // false=ascending, true=descending

在 Laravel 中将数字作为文本排序。

希望这非常有帮助。


-1

对生成的集合进行排序

$unorderedThings = Thing::orderBy('id')->get();
$orderedThings=$unorderedThings->sort();

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接