Search code examples
phpdepth-first-search

How to resolve hierarchy function within php


I have a situation in which there is an ID which I receive in a function. This ID when I pass to an API it provides me a relation list, for example if I pass as an ID A, I get:

From To Type
A B RelationType1
A C RelationType2
C D RelationType3
D A RelationType4

Now I need to find in a recursive manner the relations for all unique ID I get (A,B,C,D) and for each I need to list down the IDs with types until I cannot find any more relations .

Finally I need to save all this data within the database which is not an issue but it will be a combination of From,To and Type.

This is being attempted in php in which I am working on using a class as the basis to start off, thus implementing DFS to do . Is there a better alternative with efficient calls to the API and faster processing.

Thanks for your help.


Solution

  • simple recursive. something like this

    basic

    class Relations {
    
       public static function getLinksFromDB(relation_id){
          return $db->array(); // return an array of matches based on the passed in $relation_id from the database, using your normal query here.
       }
       public static function getLinks(relation_id){
           $ret = [];
           $r_ids = Relations::getLinksFromDB(r_id); // when this returns nothing, you will have reached the end of your links, with an exception, if you have any amount which is self contained like A->B, B->C and C->A, then you will have an infinite loop. this could be solved by passing in a counter and once it reaches the counter of depth, just return.
           foreach($r_ids as $r_id){
               $ret[] = Relations::getLinks($r_id);
           }
           return $ret;
       }
    }
    

    with depth limitor

    class Relations {
    
       public static function getLinksFromDB(relation_id){
          return $db->array(); // return an array of matches based on the passed in $relation_id from the database, using your normal query here.
       }
       public static function getLinks(relation_id, $counter){
           if($counter <= 0){
              return [];
           }
           $ret = [];
           $r_ids = Relations::getLinksFromDB(r_id);
           foreach($r_ids as $r_id){
               $ret[] = Relations::getLinks($r_id, $counter - 1);
           }
           return $ret;
       }
    }
    

    both can be called as such:

    $ids = ['A', 'B', 'C'];
    $links = [];
    foreach($ids as $id){
     $links[] = Relations::getLinks($id);
    }
    

    or with the depth limit

    $ids = ['A', 'B', 'C'];
    $links = [];
    foreach($ids as $id){
     $links[] = Relations::getLinks($id, 20);
    }