DreamT has asked for the wisdom of the Perl Monks concerning the following question:

Hi,

I want to create a tree menu from a list of values that comes something this:
... CDs Books|Adventure Movies|Music Books Books|Sports Movies Movies|Adventure Books|Drama CDs|Classic ...

-There can be maximum 5 levels for now. If it's possible to make an entirely dynamic solution that would be great, but it's not necessary.

- As you can see, the category names may be used in several positions, but every row comes with a row of matching unique id:s, so Books|Drama will have for example 2|10. "Drama" can be used in several places and levels, and will always have the number 10 assigned, but there can also be another "Drama" category with another id. So I guess that the id is the key here (i.e. every id can have any name)

Basically, I need to create the tree structure based on the ids, with the names as a property of the id.
I don't have a good way of illustrating of how I want it to be, but I hope you get the idea...I hope you understand what I'm writing, am a bit tired:-)

Replies are listed 'Best First'.
Re: Creating a tree menu from list (AoA, HoH)
by roboticus (Chancellor) on Sep 23, 2010 at 22:44 UTC

    DreamT:

    This ought to give you a head start. However, you didn't specify your problem very well, as I have no idea what type of treemenu you're wanting. (Web? Tk? Windows? ...?) So the code builds a hash containing the structure of your treemenu. Just add the appropriate code in dumptree to build your menu in whatever UI you need.

    Roboticus@Roboticus-PC ~ $ cat treemenu.pl use strict; use warnings; my %menu; my $hr; while (<DATA>) { chomp; my @keys = split /\|/,$_; next if @keys < 1; $hr = \%menu; while (my $k=shift @keys) { $$hr{$k} = {} unless exists $$hr{$k}; $hr = $$hr{$k}; } } dumptree('', \%menu); sub dumptree { my $indent = shift; my $hr = shift; for my $k (sort keys %$hr) { print $indent, $k, "\n"; if (keys %{$$hr{$k}}) { dumptree($indent." ", $$hr{$k}); } } } __DATA__ CDs Books|Adventure Movies|Music Books Books|Sports Movies Movies|Adventure Books|Drama CDs|Classic Roboticus@Roboticus-PC ~ $ perl treemenu.pl Books Adventure Drama Sports CDs Classic Movies Adventure Music Roboticus@Roboticus-PC ~ $

    ...roboticus

      Hi,
      I'm supposed to build a nested ul/li list. I think that this will do the trick:) Thank you!
Re: Creating a tree menu from list (AoA, HoH)
by Anonymous Monk on Sep 23, 2010 at 22:34 UTC

    Split each line on the divider (eg, split /\|/, ...) to get one or more fields. If there's one field, make sure a key with that value exists in some hash. If there's one field, push the second field's value onto the value (an array reference) associated with the first field (all this in the same hash mentioned before). If there are more levels, decide whether you want the third, etc fields to be sibling to the second value or children of it.

    For example, for sibling-only behavior:

    my %menu_structure; for (@menu_specification) { my ($toplevel, @sublevel) = split /\|/; unless (@fields) { $menu_structure{$toplevel} = []; } else { push @{ $menu_structure{$toplevel} }, @sublevel; } }