Get path from adjacency list data

落爺英雄遲暮 提交于 2019-12-04 14:23:49

问题


I have an array (data from adjacency table) and it looks like:

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
        )
)

And I'm looking for the way to retrieve my path by 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;

How can I do this? Thanks!


回答1:


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);



回答2:


Consider this array,

$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]
];

and this function,

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 ⟶
}

Reading echo path(13, $input); will return

Anniversary ⟶ New arrives ⟶ Discount

Here is minified version of the same function

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));}

Thanks to code reviewers Loufylouf and Quill




回答3:


$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);


来源:https://stackoverflow.com/questions/31049955/get-path-from-adjacency-list-data

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!