Beefy Boxes and Bandwidth Generously Provided by pair Networks
Don't ask to ask, just ask

For loop: Hash

by nickt9999 (Acolyte)
on Jul 02, 2013 at 08:21 UTC ( #1041977=perlquestion: print w/replies, xml ) Need Help??
nickt9999 has asked for the wisdom of the Perl Monks concerning the following question:

Hi I am a newbie to Perl. I am after some advice on if what I have come up with is the best way.

I have a hash ref

my $router_href = {}; ### Router 1 $router_href->{1}{'routerName'} = 'asr01' ; $router_href->{1}{'ipAddr'} = '' ; ### BGP Peer : 1 $router_href->{1}{'bgpPeer'}{1}{'Name'} = 'PEER1' ; $router_href->{1}{'bgpPeer'}{1}{'ASN'} = '111'; $router_href->{1}{'bgpPeer'}{1}{'prefixList'} = 'PREFIX-PEER1-OUT' ; ### BGP Peer : 2 $router_href->{1}{'bgpPeer'}{2}{'Name'} = 'PEER2'; $router_href->{1}{'bgpPeer'}{2}{'ASN'} = '222' ; $router_href->{1}{'bgpPeer'}{2}{'prefixList'} = 'PREFIX-PEER2-OUT' ; ### Router 2 $router_href->{2}{'routerName'} = 'asr02' ; $router_href->{2}{'ipAddr'} = '' ; ### BGP Peer : 1 $router_href->{2}{'bgpPeer'}{1}{'Name'} = 'PEER1' ; $router_href->{2}{'bgpPeer'}{1}{'ASN'} = '333'; $router_href->{2}{'bgpPeer'}{1}{'prefixList'} = 'PREFIX-PEER1-OUT' ;

I would like to iterate through the routers and print the prefixList

I dont know if my data structure is the best way of doing it, I am open to suggestions :-)

This is what I have managed to come up with

my $rtrId = '1'; for my $rtr ( keys %{$router_href}) { print $router_href->{$rtrId}{routerName} . " : " . "\n"; my $rplId = '1'; for my $pfxList ( keys %{$router_href->{$rtrId}{bgpPeer}} ) { print $router_href->{$rtrId}{bgpPeer}{$rplId}{prefixLi +st} . "\n"; $rplId++; } $rtrId++ }

Thanks in advance


Replies are listed 'Best First'.
Re: For loop: Hash
by hdb (Prior) on Jul 02, 2013 at 08:47 UTC

    My principles are:

    • for plain lists use arrays (or array references),
    • for lists with named attributes use hashes (or hash references).
    So both on the router level and on the peer level you have plain lists, otherwise you have named attributes. So I would propose the following, which also allows for a simpler iteration over the structure:

    use strict; use warnings; my $router_data = [ # array of hashes for each router { # hash for router 1 routerName => 'asr01', ipAddr => '', bgpPeer => [ # array of hashes for each peer { # hash for first peer Name => 'PEER1', ASN => '111', prefixList => 'PREFIX-PEER1-OUT', }, { # hash for second peer Name => 'PEER2', ASN => '222', prefixList => 'PREFIX-PEER2-OUT', }, ], }, { # hash for router 2 routerName => 'asr02', ipAddr => '', bgpPeer => [ # array of hashes for each peer { # hash for first peer Name => 'PEER1', ASN => '333', prefixList => 'PREFIX-PEER1-OUT', } ], }, ]; for my $router ( @$router_data ) { print $router->{routerName}." : \n"; for my $peer ( @{ $router->{bgpPeer} } ) { print $peer->{prefixList}."\n"; } }
      This is a great answer. To expand on it, the OP mentions that he is new to Perl, and perhaps an early programmer (or not, I don't know). Once you start using this layout, and you are finding that you need more logic and functionality against a Router, or a Peer, then it will be easy to break that part of the structure out into a class of its own.

      Many thanks for this.

      I have used this as the way forward.



Re: For loop: Hash
by Happy-the-monk (Abbot) on Jul 02, 2013 at 08:58 UTC

    No objection to what hdb said above.
    If you have to use the exact data structure you presented above, this might be the way to go:

    for my $i ( sort keys %{$router_href} ) { for my $j ( sort keys %{$router_href->{$i}->{bgpPeer}} ) { print "($i:$j) " , $router_href->{$i}{bgpPeer}{$j}{Name} , ":\t" , $router_href->{$i}{bgpPeer}{$j}{prefixList} , "\n" } }

    Cheers, Sören

    (hooked on the Perl Programming language)

Log In?

What's my password?
Create A New User
Node Status?
node history
Node Type: perlquestion [id://1041977]
Approved by hdb
Front-paged by Corion
[kcott]: marioroy, not much to go on. Searching "slow logging" (by me) produces no results; just "slow" gives a screenful. Perhaps, "Searching large files a block at a time" which had a performance aspect and you had some imput also.
[gnosti]: Hi, Looking for a module that can add HH:MM:SS durations like 1:40, 1:00:24.13 and 12.3? I see on CPAN more modules with absolute dates. TIA
[kcott]: s/imput/input/
[Corion]: DateTime::Duration ? Personally,I convert stuff to seconds using Time::Piece or Time::Local and then add the seconds and then use POSIX::strftime to print them as hours again

How do I use this? | Other CB clients
Other Users?
Others studying the Monastery: (7)
As of 2017-08-18 08:51 GMT
Find Nodes?
    Voting Booth?
    Who is your favorite scientist and why?

    Results (297 votes). Check out past polls.