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

Laravel中REST API一维数组转树形及Carbon日期格式处理求助

Laravel 一维数组转树形结构+日期转换解决方案

一、SQL Server 日期转 Carbon 格式

两种简单实现方式,按需选择:

模型自动转换(推荐)

在对应数据模型中通过$casts属性指定日期字段类型,Laravel 会自动将 SQL Server 返回的日期转为 Carbon 实例:

class YourModel extends Model
{
    protected $casts = [
        'created_at' => 'datetime',
        'updated_at' => 'datetime',
        'custom_date_column' => 'datetime', // 替换为你的日期字段名
    ];
}

手动转换(直接查询时用)

如果是通过 DB 门面直接查询,可手动遍历转换:

$rawData = DB::table('your_table')->get();
$processedData = $rawData->map(function ($item) {
    $item->custom_date_column = \Carbon\Carbon::parse($item->custom_date_column);
    // 其他日期字段同理处理
    return $item;
});

二、一维数组转树形结构(最多4级)

假设你的一维数据中,每个节点包含Initials(节点标识)和parent_initials(父节点标识)两个核心关联字段,以下提供两种实现方案:

方案1:迭代式构建(直观易调试)

适合固定最多4级的场景,避免递归深度问题:

// 1. 先将数据按 Initials 分组,方便快速查找
$itemsMap = $processedData->keyBy('Initials');

// 2. 初始化树形结构,根节点为 Initials=NF 的数据
$tree = [];
$rootNode = $itemsMap->get('NF');

if ($rootNode) {
    $rootNode['children'] = [];

    // 3. 构建第2级子节点(根节点的直接子节点)
    $level2Nodes = $itemsMap->filter(fn($item) => $item->parent_initials === 'NF');
    foreach ($level2Nodes as $node2) {
        $node2['children'] = [];

        // NR 节点不需要子节点,跳过后续层级
        if ($node2->Initials === 'NR') {
            $rootNode['children'][] = $node2;
            continue;
        }

        // 4. 构建第3级孙节点
        $level3Nodes = $itemsMap->filter(fn($item) => $item->parent_initials === $node2->Initials);
        foreach ($level3Nodes as $node3) {
            $node3['children'] = [];

            if ($node3->Initials === 'NR') {
                $node2['children'][] = $node3;
                continue;
            }

            // 5. 构建第4级曾孙节点(最多到这一级)
            $level4Nodes = $itemsMap->filter(fn($item) => $item->parent_initials === $node3->Initials);
            foreach ($level4Nodes as $node4) {
                $node3['children'][] = $node4;
            }

            $node2['children'][] = $node3;
        }

        $rootNode['children'][] = $node2;
    }

    $tree[] = $rootNode;
}

return response()->json($tree);

方案2:递归式构建(代码更简洁)

适合层级逻辑灵活的场景,通过递归控制最大层级:

// 先完成日期转换和数据分组
$itemsMap = $processedData->keyBy('Initials');

// 递归构建子节点的函数
function buildChildNodes($parentInitials, $currentLevel, $maxLevel, $itemsMap) {
    // 超过最大层级或当前是NR节点,返回空数组
    if ($currentLevel >= $maxLevel || $parentInitials === 'NR') {
        return [];
    }

    // 筛选当前父节点的子节点
    $childNodes = $itemsMap->filter(fn($item) => $item->parent_initials === $parentInitials)->values();

    // 递归处理子节点的子节点
    return $childNodes->map(function ($node) use ($currentLevel, $maxLevel, $itemsMap) {
        $node['children'] = buildChildNodes($node->Initials, $currentLevel + 1, $maxLevel, $itemsMap);
        return $node;
    })->toArray();
}

// 构建最终树形结构
$tree = [];
$rootNode = $itemsMap->get('NF');
if ($rootNode) {
    $rootNode['children'] = buildChildNodes($rootNode->Initials, 1, 4, $itemsMap);
    $tree[] = $rootNode;
}

return response()->json($tree);

三、常见问题排查

  • 父子关联错误:如果你的数据不是用parent_initials关联父子,需替换代码中对应的关联字段名(比如parent_id)。
  • 日期转换失败:若 SQL Server 返回的日期格式特殊,可指定格式解析,例如Carbon::createFromFormat('Y-m-d H:i:s', $item->custom_date_column)。
  • 层级嵌套异常:检查过滤条件是否匹配,确保子节点的父标识与父节点的Initials完全一致(注意大小写)。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.15 22:05:20