У меня есть массив (данные из таблицы смежности), и он выглядит так:
Array ( [0] => Array ( [id] => 1 [name] => Anniversary [parent] => 0 ) [1] => Array ( [id] => 12 [name] => New arrives [parent] => 1 ) [2] => Array ( [id] => 13 [name] => Discount [parent] => 12 ) [3] => Array ( [id] => 6 [name] => Birthday [parent] => 0 ) )
И я ищу способ получить мой путь по ID;
For example: getPath(13): Anniversary->New arrives->Discount; For example: getPath(12): Anniversary->New arrives; For example: getPath(1): Anniversary; For example: getPath(6): Birthday;
Как я могу это сделать? Благодаря!
function getpath($id, $arr, $level = 0) { $result = array(); foreach($arr as $key => $value){ if($id == $value['id']){ $result[] = $value['name']; $id = $value['parent']; if($id != 0){ $result = array_merge($result, getpath($id, $arr, $level+1)); }else{ break; } } } return $level ? $result : implode('->',array_reverse($result)); } echo getpath(13,$arr);
Рассмотрим этот массив,
$input = [ ['id'=>1, 'name'=>'Anniversary', 'parent'=>0], ['id'=>12, 'name'=>'New arrives', 'parent'=>1], ['id'=>13, 'name'=>'Discount', 'parent'=>12], ['id'=>6, 'name'=>'Birthday', 'parent'=>0] ];
и эта функция,
function path($element_id, $input, $ids = []) { if(!$ids) // for performance, make this once and pass it around { $ids = array_column($input, 'id'); // array containing only 'id's of $input } $current_key = array_search($element_id, $ids); // search for $input variable's current key unset($ids[$current_key]); // unsetting used keys to make above array search faster next time $current_element = $input[$current_key]; // get current element as array from $input $names[] = $current_element['name']; // create an array containing current element if($current_element['parent'] != 0) // check if current element have parent { $names[] = path($current_element['parent'], $input, $ids); // call this function, let it return string, append it to $names } return implode(' ⟶ ', array_reverse($names)); // make final return, seprate by ⟶ }
неfunction path($element_id, $input, $ids = []) { if(!$ids) // for performance, make this once and pass it around { $ids = array_column($input, 'id'); // array containing only 'id's of $input } $current_key = array_search($element_id, $ids); // search for $input variable's current key unset($ids[$current_key]); // unsetting used keys to make above array search faster next time $current_element = $input[$current_key]; // get current element as array from $input $names[] = $current_element['name']; // create an array containing current element if($current_element['parent'] != 0) // check if current element have parent { $names[] = path($current_element['parent'], $input, $ids); // call this function, let it return string, append it to $names } return implode(' ⟶ ', array_reverse($names)); // make final return, seprate by ⟶ }
Чтение echo path(13, $input);
вернется
Anniversary ⟶ New arrives ⟶ Discount
Здесь приведена миниатюрная версия той же функции
function path($a,$b,$c=[]){if(!$c){$c=array_column($b,'id');}$d=array_search($a,$c);unset($c[$d]);$e=$b[$d];$f[]=$e['name'];if($e['parent']!=0){$f[]=path($e['parent'],$b,$c);}return implode(' ⟶ ',array_reverse($f));}
Благодаря рецензентам кода Loufylouf и Quill
$find = 13; $path = array(); function FindById ($arr, $find) { $k = null; foreach($arr as $key => $item) if ($item['id'] == $find) { $k = $key; break; } return $k; } if ( false === ($k = FindById($arr, $find))) die("not found"); while (true) { array_unshift($path, $arr[$k]['name']); if( ! $arr[$k]['parent']) break; if(false === ($k = FindById($arr, $arr[$k]['parent']))) die("illegal structure"); } echo implode('->', $path);