我有一个多维数组,如下面的示例所示,我想搜索特定值$ 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' => [],
],
],
],
],
],
答案 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);
*/