Convert a series of parent-child relationships into a hierarchical tree?

前端 未结 11 1931
[愿得一人]
[愿得一人] 2020-11-22 07:04

I have a bunch of name-parentname pairs, that I\'d like to turn into as few heirarchical tree structures as possible. So for example, these could be the pairings:

         


        
11条回答
  •  太阳男子
    2020-11-22 07:34

    Old question, but I too had to do this and the examples with recursion gave me a headache. In my database we have a locations table, which was a loca_id PK (Child) and self referencing loca_parent_id (Parent).

    The aim is to represent this structure in HTML. The simple query can of couyrse return the data is some fixed order but I found not well enough to display such data in a natural way. What I really wanted was Oracle tree walk handling with LEVEL to help with display.

    I decided to use the idea of a 'path' to uniquely identify each entry. For example:

    Sorting the array by the path should make it easier to process for meaningful display.

    I realise that use of associative arrays and sorts is cheating as it hides the recursive complexity of the operations, but to me this look simpler:

    prepare($sql);
        $stmt->execute();
        $result = $stmt->get_result();
        $data = $result->fetch_all(MYSQLI_ASSOC);
        
        $printed = array();
        
        // To get tree hierarchy usually means recursion of data.
        // Here we will try to use an associate array and set a
        // 'path' value to represent the hierarchy tree in one
        // pass. Sorting this array by the path value should give
        // a nice tree order and reference.
    // The array key will be the unique id (loca_id) for each row.
    // The value for each key will the complete row from the database.
    // The row contains a element 'loca_path' - we will write the path
    // for each row here. A child's path will be parent_path/child_name.
    // For any child we encounter with a parent we look up the parents path
    // using the loca_parent_id as the key.
    // Caveat, although tested quickly, just make sure that all parents are
    // returned first by the query.
        
        foreach ($data as $row)
        {
        
           if ( $row['loca_parent_id'] == '' ) // Root Parent
           {
              $row['loca_path'] = $row['loca_name'] . '/';
              $printed[$row['loca_id']] = $row;
           }
           else // Child/Sub-Parent
           {
              $row['loca_path'] = $printed[$row['loca_parent_id']]['loca_path'] . $row['loca_name'] . '/';
              $printed[$row['loca_id']] = $row;
           }
        }
        
        // Array with paths built, now sort then print
        
        array_multisort(array_column($printed, 'loca_path'), SORT_ASC, $printed);
        
        foreach ( $printed as $prow )
        {
           print_row ( $prow );
        }
        ?>
        

提交回复
热议问题