1

I have an object from a sql-query. Every entry has the keys (id, type, title, parent_id).

My example data:

Content of the sql-object $list (var_export()):

$array = array(0 => (object) array( 'id' => 1, 'type' => 'label', 'title' => 'Product Categories', 'parent_id' => 0, ), 
               1 => (object) array( 'id' => 2, 'type' => 'label', 'title' => 'Shoes', 'parent_id' => 1, ), 
               2 => (object) array( 'id' => 3, 'type' => 'label', 'title' => 'T-Shirts', 'parent_id' => 1, ), 
               3 => (object) array( 'id' => 4, 'type' => 'label', 'title' => 'With Print', 'parent_id' => 2, ), 
               4 => (object) array( 'id' => 5, 'type' => 'label', 'title' => 'Without Print', 'parent_id' => 2, ), 
               5 => (object) array( 'id' => 6, 'type' => 'label', 'title' => 'Brands', 'parent_id' => 2, ), 
               6 => (object) array( 'id' => 7, 'type' => 'label', 'title' => 'Blue', 'parent_id' => 3, ), 
               7 => (object) array( 'id' => 8, 'type' => 'label', 'title' => 'Red', 'parent_id' => 3, ));

What i expect:

the function, should find the dependencies of the entries starting with a given id. Here for example the ID 7:

Array
(
    [0] => stdClass Object
        (
            [id] => 7
            [type] => "label"
            [title] => "Blue"
            [parent_id] => 3
        )
    [1] => stdClass Object
        (
            [id] => 3
            [type] => "label"
            [title] => "T-Shirts"
            [parent_id] => 1
        )
    [2] => stdClass Object
        (
            [id] => 1
            [type] => "label"
            [title] => "Product Categories"
            [parent_id] => 0
        )
)

What i get:

I just get an array with the first entry, with the id I started with. As example with starting ID 7:

array ( 0 => (object) array( 'id' => 7, 'type' => 'label', 'title' => 'Blue', 'parent_id' => 3, ), ) 

My current Function:

The function needs to search for the item with the given id, stores the information into a new array and then start a new search but with the parent_id as new search id. This should loop as long as there are dependencies, if there are no dependencies the loop should stop and returning the created array.

function getParentSelect($list, $parent) {
    $next_id = true;
    $result = array();    
    foreach($list as $k => $s) {
        echo $s->id;
        if ($s->id == $parent) {
            $result[] = $s;
            $next_id = $s->parent_id;                                     
            break;
        }
        else {
            $next_id = false;
        }
    }
    if ($next_id != false) {
        $result = array_merge($result, getParentSelect($list, $next_id));
    }
    return $result;
}
KIKO Software
  • 15,283
  • 3
  • 18
  • 33
Change
  • 25
  • 6
  • Topically related: [php recursive get parents](https://stackoverflow.com/q/24350829/2943403) , [Get names of parents recursively](https://stackoverflow.com/q/58807935/2943403) , [How can I recursively get the IDs of all the parent elements in a multidimensional array?](https://stackoverflow.com/q/26704931/2943403) – mickmackusa Feb 12 '23 at 23:56

1 Answers1

2

Recursion is always somewhat difficult to understand. I think you got the main idea, but the execution was flawed. This is what I can up with:

function getParentSelect($list, $select_id) {
    $result = [];    
    foreach($list as $s) {
        if ($s->id == $select_id) {
            $result = array_merge([$s], getParentSelect($list, $s->parent_id));
        }
    }
    return $result;
}

The assumption here is that all the parent id's are valid.

How does the code work?

The function itself searched the whole list for items with the id that was selected. If it finds one it will add it to the results, but it also looks for any parents of that item. This is where the function recurses. This means that the function can also look for parents of parents, and so on. array_merge() is used to combine the items and all parents together to form the results.

KIKO Software
  • 15,283
  • 3
  • 18
  • 33
  • 1
    [a variadic array_push()](https://3v4l.org/Xs1OJ) also works instead of `array_merge()`. – mickmackusa Feb 12 '23 at 23:52
  • please take a moment (when you can) to explain your snippet with the intention to educate the asker and thousands of future researchers. Also, it would be best for Stack Overflow if you would edit the question to give it a highly searchable title, format the sample data to reduce horizontal scrolling, and add the recursion tag. – mickmackusa Feb 13 '23 at 01:18
  • @mickmackusa: I did my best, feel free to edit if something isn't right. It's a bit awkward to change someone else's title so drastically. I know you're not happy with answers to questions that have duplicates. This is the problem of Stack Overflow. Is it a forum where people can ask question that are new to them, and reasonably expect an answer? This is the way most newcomers see Stack Overflow. Or is it a knowledge base, to which new knowledge can be added, but should be defended against duplication of questions? I think Stack Overflow tries to be both. That creates tension. – KIKO Software Feb 13 '23 at 02:03
  • Regarding your authority to "drastically" edit, please dismiss your feelings about awkwardness. Stack Overflow absolutely DOES want you to edit questions into their best, most valuable form for future readers (and AI bots). In fact, they want you to do it ASAP -- see the [Illuminator badge](https://stackoverflow.com/help/badges/4370/illuminator) You are a PHP Subject Matter Expert (SME) regardless of whether Stack Overflow identifies you as a bronze, silver, or gold badge holder. Your curation routine makes a big difference because you are a frequent contributor. – mickmackusa Feb 13 '23 at 03:14
  • Closing duplicates was never designed by the system or the community to punish askers. By closing duplicates we help to compile advice on the same task/topic in one place for easiest researcher consumption. I don't know that this page is a duplicates, so I didn't not re-close it; I merely linked other related pages to help researchers. At the end of the day we must put "future researchers" as the top priority -- this is absolutely in line with the mission of Stack Overflow. This goal in no way guarantees that every asker is entitled to receiving answers to their specific question. – mickmackusa Feb 13 '23 at 03:15