Accessing and printing LoL fields in a loop?

T

Tuxedo

Given this data structure:

my @lol = ('level 1.1',
['level 2.1',
'level 2.2',
['level 3.1',
'level 3.2'],
'level 2.3']);

How can I print the LoL with a loop, in the same basic structure, as
follows:

<ul><li>level 1.1
<ul><li>level 2.1</li>
<li>level 2.2
<ul><li>level 3.1</li>
<li>level 3.2</li>
</ul>
</li>
<li>level 2.3</li>
</ul>
</li>
</ul>

And how can I access/print separate level records, such as all in the first
level of the LoL, the second level or the third? Again by a loop. For
example, the output of printing all items in the first level would return:

level 1.1

or in the second level:

level 2.1, level 2.2, level 2.3

or the third level:

level 3.1, level 3.2

I guess a simple way to do this exists? However, I cannot find any similar
examples anywhere.

Many thanks for any tips.

Tuxedo
 
U

Uri Guttman

T> Given this data structure:
T> my @lol = ('level 1.1',
T> ['level 2.1',
T> 'level 2.2',
T> ['level 3.1',
T> 'level 3.2'],
T> 'level 2.3']);

T> How can I print the LoL with a loop, in the same basic structure, as
T> follows:

have you read perldoc perllol? it directly answers your question.

uri
 
J

Jürgen Exner

Tuxedo said:
Given this data structure:

my @lol = ('level 1.1',
['level 2.1',
'level 2.2',
['level 3.1',
'level 3.2'],
'level 2.3']);

How can I print the LoL with a loop,

You cannot. At least not withouth building your own data stack to
simulate recursion. Which can be done but why would you want to?
in the same basic structure, as follows:

<ul><li>level 1.1
<ul><li>level 2.1</li>
<li>level 2.2
<ul><li>level 3.1</li>
<li>level 3.2</li>
</ul>
</li>
<li>level 2.3</li>
</ul>
</li>
</ul>

Recursion is your friend:
(untested, algorithmic sketch only):

sub print_list {
print_list_begin();
for my $elem (@_){
if (ref($elem) { # we got a sublist to process
print_list @{$elem};
} else { # we got a single element
print_item($elem};
}
}
print_list_end()
}
And how can I access/print separate level records, such as all in the first
level of the LoL, the second level or the third? Again by a loop.

Again, you cannot unless you implement recursion yourself.

However if you don't insist on that loop then just pass an additional
parameter "$level" to print_list() which you decrement for each
recursive call and the actual print()s are only executed if $level ==0;

sub print_list {
my $level = shift;
print_list_begin() if $level ==0;;
for my $elem (@_){
if (ref($elem) { # we got a sublist to process
print_list ($level -1, @{$elem});
} else { # we got a single element
print_item($elem} if $level ==0;;
}
}
print_list_end() if $level ==0;
}

I guess a simple way to do this exists?

No. Implementing general recursive algorightm using loops is rather
difficult except in the case of tail recursion which is trivial but
doesn't apply here.
For general recursion you need to maintain some sort of data or
call-back stack manually, otherwise the loop would not know how to
proceed after returning from processing a sub list.

jue
 
T

Tuxedo

Uri Guttman wrote:

[...]
have you read perldoc perllol? it directly answers your question.

I indeed have, understood everything within, unfortunately not. As such, I
can't say there are direct answers to my questions in the documentation, at
least not ones intended for readers at my current level of perl knowledge.

Tuxedo
 
T

Tuxedo

Jürgen Exner said:
Tuxedo said:
Given this data structure:

my @lol = ('level 1.1',
['level 2.1',
'level 2.2',
['level 3.1',
'level 3.2'],
'level 2.3']);

How can I print the LoL with a loop,

You cannot. At least not withouth building your own data stack to
simulate recursion. Which can be done but why would you want to?
in the same basic structure, as follows:

<ul><li>level 1.1
<ul><li>level 2.1</li>
<li>level 2.2
<ul><li>level 3.1</li>
<li>level 3.2</li>
</ul>
</li>
<li>level 2.3</li>
</ul>
</li>
</ul>

Recursion is your friend:
(untested, algorithmic sketch only):

sub print_list {
print_list_begin();
for my $elem (@_){
if (ref($elem) { # we got a sublist to process
print_list @{$elem};
} else { # we got a single element
print_item($elem};
}
}
print_list_end()
}
And how can I access/print separate level records, such as all in the
first level of the LoL, the second level or the third? Again by a loop.

Again, you cannot unless you implement recursion yourself.

However if you don't insist on that loop then just pass an additional
parameter "$level" to print_list() which you decrement for each
recursive call and the actual print()s are only executed if $level ==0;

sub print_list {
my $level = shift;
print_list_begin() if $level ==0;;
for my $elem (@_){
if (ref($elem) { # we got a sublist to process
print_list ($level -1, @{$elem});
} else { # we got a single element
print_item($elem} if $level ==0;;
}
}
print_list_end() if $level ==0;
}

I guess a simple way to do this exists?

No. Implementing general recursive algorightm using loops is rather
difficult except in the case of tail recursion which is trivial but
doesn't apply here.
For general recursion you need to maintain some sort of data or
call-back stack manually, otherwise the loop would not know how to
proceed after returning from processing a sub list.

jue

Thanks for answering and posting the above code examples. I can't say I
fully understand the syntax (yet). How is parameter $level passed to
print_list() for example? Would this be done with a regular LoL or
something slightly different? Can you or anyone kindly post the code within
an actual working script using example data like in the above LoL?

Thanks again,
Tuxedo
 
J

Jürgen Exner

Tuxedo said:
Jürgen Exner wrote:
Thanks for answering and posting the above code examples. I can't say I
fully understand the syntax (yet).

You see me bedazzled. I'm not using any special syntax tricks, it's all
_very_ basic stuff that you would find in virtually identical form in
hundreds of other programming languages: function definition,
assignments, conditional statements (ok, this might be a tiny bit less
common), conditional, expressions, and function calls.
How is parameter $level passed to
print_list() for example?

It's right in there, you just do it (well, you pass $level-1, not
$level):
print_list ($level -1, @{$elem});
Would this be done with a regular LoL or
something slightly different?

???
Neither, nor. You just pass it on it's own accord. No need to hide it in
some additional data structure.

Or are you confused that you can pass more than one parameter to a
function?

jue
 
T

Tuxedo

Sherm Pendley wrote:

[...]
As it happens, the menus on my CamelBones site are generated from a
similar data structure. This script runs in my editor (BBEdit) to update
static .html pages, so you'll need to make the appropriate adjustments
to adapt it to your specific needs:

Hey that's cool! Thanks for sharing your work! I really like the navigation
system at http://camelbones.sourceforge.net. I must use this the same for
something; not an exact replica of course but a slightly amended version :)

As far as I understand, a nested list system is created based on the
directory depth levels of your site. Is that right? What arguments and in
which order they meant to me passed if running/testing menu.pl on the
command line?

My particular menu however is only for pages that are at a root directory
level, yet they should always have the same nested <li> levels returned as
represented in its list structure:

my $menu = [
{ 'title' => 'Level 1.1 (node)', 'href' => '1.1.html', 'children' =>[
{ 'title' => 'Level 2.1', 'href' => '2.1.html', },
{ 'title' => 'Level 2.2 (node)', 'href' => '2.2.html', 'children' =>[
{ 'title' => '3.1.html', 'href' => '3.1.html', },
{ 'title' => '3.2', 'href' => '3.2.html', },
]},
{ 'title' => 'Level 2.3', 'href' => '2.3.html', },
]},
];

The flat HTML (without any current URL paramenter) it should produce is:

<ul>
<li><a href=1.1.html>Level 1.1 (node)</a>
<ul>
<li><a href=2.1.html>Level 2.1</a></li>
<li><a href=2.2.html>Level 2.2 (node)</a>
<ul>
<li><a href=3.1.html>Level 3.1</a></li>
<li><a href=3.2.html>Level 3.2</a></li>
</ul>
</li>
<li><a href=2.3.html>Level 2.3</a></li>
</ul>
</li>
</ul>

Maybe slightly unusual in that I have only one item at level 1. Obviously
the real version will be populated with many more items. Anyhow, is your
script adaptable to this format? I guess not without a major rewrite!?

Thanks,
Tuxedo
 
T

Tuxedo

Jürgen Exner wrote:

[...]
You see me bedazzled. I'm not using any special syntax tricks, it's all

I never thought so, especially as you comment your code, which is only
helpful.
_very_ basic stuff that you would find in virtually identical form in
hundreds of other programming languages: function definition,
assignments, conditional statements (ok, this might be a tiny bit less
common), conditional, expressions, and function calls.

Fortunately I don't think there are that many programming languages to
learn. I'm still battling with one to produce basic things like a simple
unordered html list with a few extra parameters like a current URL and tree
stem node indications...
It's right in there, you just do it (well, you pass $level-1, not
$level):
print_list ($level -1, @{$elem});


???
Neither, nor. You just pass it on it's own accord. No need to hide it in
some additional data structure.

Or are you confused that you can pass more than one parameter to a
function?

No, that much I should know. Don't worry about my dumb questions, it's just
me trying to figure how to join your procedure with my list while not
necessarily fully understanding the general syntax of perl. If there is
anything that doesn't add up, it's always hard for me to find where to fix
it. That said, I will test your code and I'm sure it will work as intended.

Thanks for your good advise.

Tuxedo
 
T

Tuxedo

Dr.Ruud wrote:

[..]
Try it, then redo it in Perl. Or google it up. Or check our archives.

I tried it and all it did was turning off the light in the fridge :)

Tuxedo
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,982
Messages
2,570,186
Members
46,740
Latest member
JudsonFrie

Latest Threads

Top