在php中将键值对添加到动态多维数组中

时间:2018-01-31 12:44:43

标签: php multidimensional-array

我有一个多维数组,如下面的示例所示,我想搜索特定值$ needle。如果找到此值,我想添加一个新密钥=>数组分支的每个节点的值对,随后找到$ needle。 针应该是唯一的,但子阵列的深度是动态的。 例如:

Fatal on LAPTOP-BGTGSTJU: Exception occurred in NLog
    2018-01-28 11:39:33.1419 Fatal error occurred during execution of 'Worker #b261e15e' process. It will be stopped. See the exception for details.
    | Exception occurred in NLog Void <Write>b__0(System.Exception)
    at NLog.LoggerImpl.<>c__DisplayClass1.<Write>b__0(Exception ex)
    at NLog.Internal.SingleCallContinuation.Function(Exception exception)
    at NLog.Targets.MailTarget.ProcessSingleMailMessage(List`1 events)
    at NLog.Targets.MailTarget.Write(AsyncLogEventInfo[] logEvents)
    at NLog.Targets.MailTarget.Write(AsyncLogEventInfo logEvent)
    at NLog.Targets.Target.WriteAsyncLogEvent(AsyncLogEventInfo logEvent)
    at NLog.LoggerImpl.WriteToTargetWithFilterChain(TargetWithFilterChain targetListHead, LogEventInfo logEvent, AsyncContinuation onException)
    at NLog.LoggerImpl.Write(Type loggerType, TargetWithFilterChain targets, LogEventInfo logEvent, LogFactory factory)
    at NLog.Logger.WriteToTargets(LogLevel level, String message, Exception ex)
    at CallSite.Target(Closure , CallSite , Object , String , Exception )
    at System.Dynamic.UpdateDelegates.UpdateAndExecuteVoid3[T0,T1,T2](CallSite site, T0 arg0, T1 arg1, T2 arg2)
    at Hangfire.Logging.LogProviders.NLogLogProvider.NLogLogger.LogException(LogLevel logLevel, Func`1 messageFunc, Exception exception)
    at Hangfire.Logging.LogProviders.NLogLogProvider.NLogLogger.Log(LogLevel logLevel, Func`1 messageFunc, Exception exception)
    at Hangfire.Logging.LoggerExecutionWrapper.Log(LogLevel logLevel, Func`1 messageFunc, Exception exception)
    at Hangfire.Server.AutomaticRetryProcess.Execute(BackgroundProcessContext context)
    at Hangfire.Server.ServerProcessExtensions.Execute(IServerProcess process, BackgroundProcessContext context)
    at Hangfire.Server.InfiniteLoopProcess.Execute(BackgroundProcessContext context)
    at Hangfire.Server.ServerProcessExtensions.Execute(IServerProcess process, BackgroundProcessContext context)
    at Hangfire.Server.ServerProcessExtensions.RunProcess(IServerProcess process, BackgroundProcessContext context)

现在,当我搜索$ needle = foxtrot时,我想添加到每个子阵列“active”=&gt; 1 E:

$data= [
    0=> [
        'title'     => 'alpha',
        'children'  => [],
        ],
    1 =>[
        'title'     => 'beta',
        'children'  => [
         0=>[
             'title'     => 'charlie',
             'children'  => [],
            ],
         1=>[
             'title'     => 'delta',
             'children'  => [],
            ],
         2=>[
             'title'     => 'echo',
             'children'  => [
            0=>[
               'title'     => 'foxtrot',
               'children'  => [],
                    ],                      
                ],
            ],              
        ],
        ],      
  2 =>  [
        'title'     => 'gulf',
        'children'  => []
  ]

我没有尝试。我不知道我是如何正确合并key =&gt;每个发现的价值:

   $data= [
    0=> ...
    1 =>[
        'title'     => 'beta',
        **'active' => 1,**
        'children'  => [
         0=>[
             'title'     => 'charlie',
             'children'  => [],
            ],
         1=>[
             'title'     => 'delta',
             'children'  => [],
            ],
         2=>[
             'title'     => 'echo',
             **'active' => 1,**
             'children'  => [
            0=>[
               'title'     => 'foxtrot',
               **'active' => 1,**
               'children'  => [],
                    ],                      
                ],
            ],              
        ],
        ], 

1 个答案:

答案 0 :(得分:1)

这是一种递归方式。我添加了内联注释来解释每一步。

代码:(Demo

function keysort($a,$b){  // this function is optional; purely used for aesthetic/readability purposes
    $order=['title'=>0,'active'=>1,'children'=>2];  // order keys by this specific order
    return $order[$a]<=>$order[$b];
}
function activate_lineage(&$array,$needle){
    foreach($array as &$item){
        if($item['title']==$needle){  // $needle located, make active
            $item['active']=1;  // add active element
            uksort($item,'keysort');  // optional call
            return $array;  // send full updated array back where it came from
        }elseif(!empty($item['children'])){  // drill down if there are any children
            $copy=$item;  // preserve original (this avoids a post-recursion column-search)
            $item['children']=activate_lineage($item['children'],$needle);  // recurse
            if($copy!==$item){  // if children subarray was updated, a child was activated
                $item['active']=1;  // add active element
                uksort($item,'keysort');  // optional call
                break;  // don't continue the loop; only one parent will be activated (per level)
            }
        }
    }
    return $array;  // return the full array, no matter what level it is on
}

// to call:
var_export(activate_lineage($data,'foxtrot'));

/* or because the function modifies by reference...

    activate_lineage($data,'foxtrot');
    var_export($data);

*/