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

PHP如何基于动态深度选择器从JSON中生成对应多层级数组

实现方案

核心逻辑是基于路径分段动态读取原数组值,同时动态创建结果数组的对应层级,全程不需要提前感知数组结构和选择器深度,具体实现如下:

完整可运行代码

<?php

function filterBySelector(string $json, string $selector): array {
    $originArr = json_decode($json, true);
    if (json_last_error() !== JSON_ERROR_NONE) {
        return [];
    }
    $result = [];
    // 拆分多个选择器
    $selectorItems = explode(',', $selector);
    foreach ($selectorItems as $item) {
        $item = trim($item);
        if (empty($item)) continue;
        // 拆分路径段
        $pathSegments = explode('.', $item);
        $segCount = count($pathSegments);
        if ($segCount < 1) continue;
        
        // 第一步:从原数组读取对应路径的值
        $currentOrigin = $originArr;
        $valueExists = true;
        foreach ($pathSegments as $seg) {
            // 兼容数字索引和字符串键
            $key = is_numeric($seg) ? (int)$seg : $seg;
            if (!isset($currentOrigin[$key])) {
                $valueExists = false;
                break;
            }
            $currentOrigin = $currentOrigin[$key];
        }
        if (!$valueExists) continue;
        $targetValue = $currentOrigin;
        
        // 第二步:动态创建结果数组层级,写入值
        // 层级路径为去掉最后一段索引的所有路径段
        $levelSegments = array_slice($pathSegments, 0, $segCount - 1);
        $currentResult = &$result;
        foreach ($levelSegments as $seg) {
            $key = is_numeric($seg) ? (int)$seg : $seg;
            // 不存在的层级自动创建空数组
            if (!isset($currentResult[$key]) || !is_array($currentResult[$key])) {
                $currentResult[$key] = [];
            }
            $currentResult = &$currentResult[$key];
        }
        // 把值追加到对应层级的数组末尾
        $currentResult[] = $targetValue;
        // 释放引用避免污染后续循环
        unset($currentResult);
    }
    return $result;
}

// 测试用例1:原始3层路径场景
$json = '
{
    "hotels" : { 
        "hotel" : [
            { "ort": "rom", "lioc": "inrom" },
            { "ort": "paris", "lioc": "inpsrisd" },
            { "ort": "berlin", "lioc": "inberlin" },
            { "ort": "milano", "lioc": "inmilano" },
            { "ort": "paris", "lioc": "anotherinpsrisd" },
            { "ort": "muc", "lioc": "inmuc" }
        ]
    }
}';
$selector = "hotels.hotel.0,hotels.hotel.5";
$result = filterBySelector($json, $selector);
echo json_encode($result) . PHP_EOL;
// 输出结果:{"hotels":{"hotel":[{"ort":"rom","lioc":"inrom"},{"ort":"muc","lioc":"inmuc"}]}}

// 测试用例2:深层级路径场景
$deepJson = '{"hotels":{"hotel":{"bla":{"bla":[{"ort":"rom","lioc":"inrom"},{},{},{},{},{"ort":"muc","lioc":"inmuc"}]}}}}';
$deepSelector = "hotels.hotel.bla.bla.0,hotels.hotel.bla.bla.5";
$deepResult = filterBySelector($deepJson, $deepSelector);
echo json_encode($deepResult) . PHP_EOL;
// 输出结果:{"hotels":{"hotel":{"bla":{"bla":[{"ort":"rom","lioc":"inrom"},{"ort":"muc","lioc":"inmuc"}]}}}}

逻辑说明

  • 先对输入JSON做合法性校验,避免解析失败抛出异常
  • 拆分选择器为多个独立路径,逐路径做校验和取值
  • 逐段遍历路径从原数组读取目标值,路径不存在直接跳过当前选择器
  • 取路径的前N-1段作为结果数组的层级路径,通过PHP引用特性动态创建不存在的层级
  • 最终把读取到的目标值追加到对应层级的数组末尾,保证结构完全匹配选择器层级
  • 全程兼容字符串键、数字索引,无需提前知晓JSON结构和选择器深度

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.01 17:39:04