You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Laravel排序后的集合传递到JavaScript后顺序错乱问题

问题:Laravel集合排序后返回Ajax,JS接收时顺序错乱

在Laravel控制器中获取包含多种测量属性的产品集合,经unique()去重、sortBy()排序后返回给Ajax函数,但Ajax接收的对象顺序错乱。控制器用dd($lengths)查看时,集合按length字段有序;但在JavaScript中,lengths对象的排序状态未保留。


控制器代码

public function attributes(Request $request) {
    $diameter = $request->diameter;
    $length = $request->length;
    $rate = $request->rate;
    $type = $request->type;

    $products = Attributes::when($diameter, function($query, $diameter) {
        $query->where('diameter', $diameter);
    })->when($length, function($query, $length) {
        $query->where('length', $length);
    })->when($rate, function($query, $rate) {
        $query->where('rate', $rate);
    })->when($type, function($query, $type) {
        $query->where('type', $type);
    })->get();
    
    $diameters = $products->unique('diameter')->sortBy('diameter');
    $lengths = $products->unique('length')->sortBy('length');
    $rates = $products->unique('rate')->sortBy('rate');
    $types = $products->unique('type')->sortBy('type');

    return ['diameters' => $diameters,'lengths' => $lengths,'rates' => $rates,'types' => $types];
}

控制器dd($lengths)输出

items: array:7 [
    9 => App\Models\Attribute
        ...
        "length" => "3.00""
        ...
    0 => 
        ...
        "length" => "4.00""
    1 => 
        ...
        "length" => "5.00""
    ....
]

JavaScript接收结果

{diameters: Array(1), lengths: {…}, rates: Array(4), types: Array(1)}
diameters
: 
[{…}]
lengths
: 
0
: 
{diameter: '2.25" I.D.', length: '4.00"', …}
4
: 
{diameter: '2.25" I.D.', length: '5.00"', …}
5
: 
{diameter: '2.25" I.D.', length: '6.00"', …}
6
: 
{diameter: '2.25" I.D.', length: '7.00"', …}
7
: 
{diameter: '2.25" I.D.', length: '8.00"', …}
8
: 
{diameter: '2.25" I.D.', length: '9.00"', …}
9
: 
{diameter: '2.25" I.D.', length: '3.00"', …}
[[Prototype]]
: 
Object
rates
: 
(4) [{…}, {…}, {…}, {…}]
types
: 
[{…}]
[[Prototype]]
: 
Object

原因&解决方法

原因

Laravel集合执行unique()和sortBy()后,仍保留原集合的非连续数字键(比如示例中的9、0、1)。当Laravel把集合转成JSON返回时,这些非连续数字键会被JS解析为对象属性,而JS对象的数字属性会被自动按升序排列,导致原本的排序失效。

解决

给每个处理后的集合调用values()方法,重置集合的键为连续索引(0、1、2...),这样转成JSON后就是JS数组,顺序会严格保留:

修改控制器中的集合处理代码:

$diameters = $products->unique('diameter')->sortBy('diameter')->values();
$lengths = $products->unique('length')->sortBy('length')->values();
$rates = $products->unique('rate')->sortBy('rate')->values();
$types = $products->unique('type')->sortBy('type')->values();

修改后,JS接收的lengths会变成有序数组,和控制器dd看到的顺序完全一致。


内容的提问来源于stack exchange,提问作者Casey

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.02 07:55:21