Beefy Boxes and Bandwidth Generously Provided by pair Networks
go ahead... be a heretic
 
PerlMonks  

hash of arrays to array of arrays

by hsfrey (Beadle)
on Jul 16, 2009 at 20:01 UTC ( [id://780833]=perlquestion: print w/replies, xml ) Need Help??

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

I'm trying to convert a hash of arrays to an array of arrays, and having problems. :-( Here's the relevant code section:
print "\n\nThe Hash Table\n\n"; foreach $thread (keys %threads) { print "$thread: @{$threads{$thread}}\n"; } #this prints out lines like: #keyA: 2 6 8 #keyB: 3 5 10 14 18 #etc. # Convert hash table into arrays for Threads, with common index $tnum $tnum=0; foreach $thread (keys %threads) { $tsub[$tnum] = $thread; @tlist[$tnum] = @{$threads{$thread}}; $tsize[$tnum] = @tlist[$tnum]; $tnum++; } print "\n\nThe Thread Arrays\n\n"; for ($i=0;$i<$tnum ;$i++) { print "\n$tsub[$i], size=$tsize[$i], @tlist[$i]"; } The printout reveals several errors: The $tsize[$i] field, instead of showing the number of items in the ar +ray, gives the first item of the array, and the @tlist[$i]field, instead of printing all the items of the @tlist a +rray, prints only the first. So the output now looks like: #keyA: 2, 2 #keyB: 3, 3 #etc.
I'm sure I've made a simple noobie syntax error. Can anyone help me find it?

Replies are listed 'Best First'.
Re: hash of arrays to array of arrays
by jwkrahn (Abbot) on Jul 16, 2009 at 20:34 UTC

    It sounds like you want something like:

    my @tsub = keys %threads; my @tlist = values %threads; my @tsize = map scalar @$_, @tlist; print "The Thread Arrays\n\n"; for my $i ( 0 .. $#tsub ) { print "$tsub[$i], size=$tsize[$i], @{$tlist[$i]}\n"; }
Re: hash of arrays to array of arrays
by psini (Deacon) on Jul 16, 2009 at 20:16 UTC

    You are trying to make an array of arrays, and this is not possible in perl.

    When you hear of AoA, it is really an array of array references! So @tlist$tnum is not doing at all what you expected, use strict; use warnings; could have given you some hints about the problem.

    I think this is more like what you were trying to achieve (not tested)

    foreach $thread (keys %threads) { $tsub[$tnum] = $thread; $tlist[$tnum] = $threads{$thread}; $tsize[$tnum] = @{$tlist[$tnum]}; $tnum++; } print "\n\nThe Thread Arrays\n\n"; for ($i=0;$i<$tnum ;$i++) { print "\n$tsub[$i], size=$tsize[$i], @{$tlist[$i]}"; }

    Now @tlist is an array of reference, and it should work.

    As a matter of style, I would write it in a slightly different fashion>

    # Define the arrays as lexical vars. # So you are sure they are not conflicting with other vars in the prog +ram my @tsub; my @tlist; foreach $thread (keys %threads) { # using push you don't need the counter push(@tsub, $thread); push(@tlist, $threads{$thread}); } print "\n\nThe Thread Arrays\n\n"; for ($i=0;$i<@tsub ;$i++) { # compute tsize only when you need it, another array is useless my $tsize=@{$tlist[$i]}; print "\n$tsub[$i], size=$tsize, @{$tlist[$i]}"; }

    Rule One: "Do not act incautiously when confronting a little bald wrinkly smiling man."

Re: hash of arrays to array of arrays
by LanX (Saint) on Jul 16, 2009 at 20:25 UTC
    What do you mean with "convert", do you need a copy of the subarrays or just themself.

    use Data::Dumper; $copy=1; #what you want? %threads=( keyA => [ 2, 6, 8 ], keyB => [ 3, 5, 10, 14, 18 ], ); $tnum=0; foreach $thread (keys %threads) { $tsub[$tnum] = $thread; $tlist[$tnum] = $threads{$thread} unless $copy; @{$tlist[$tnum]} = @{$threads{$thread}} if $copy; $tsize[$tnum] = @{$tlist[$tnum]}; $tnum++; } print Dumper \@tsub,\@tlist,\@tsize;

    # OUTPUT

    there are more elegant ways using arrayslices but I think you should first start to understand perlref

    Cheers Rolf

    UPDATE: Who cares, here a solution with slices (no copy)

    @tsub2 = keys %threads; @tlist2 = @threads{@tsub2}; @tsize2 = map { scalar @{$_} } @tlist2; print Dumper \@tsub2,\@tlist2,\@tsize2;

    hmmm that solution without slices is even simpler, I wasn't sure that the order of keys and values are guarantied, but it's documented so, as long as the hash isn't modified.

Re: hash of arrays to array of arrays
by goibhniu (Hermit) on Jul 17, 2009 at 14:47 UTC

    You might also find perldsc useful.


    #my sig used to say 'I humbly seek wisdom. '. Now it says:
    use strict;
    use warnings;
    I humbly seek wisdom.
Re: hash of arrays to array of arrays
by spazm (Monk) on Jul 16, 2009 at 20:14 UTC
    What are you trying to do in this line:
    @tlist[$tnum] = @{$threadds{$thread};

    Can you give an example of the input you have and the output you expect?

      Ok, I think I see what you're trying to do.

      1. walk through threads
      2. each key in threads points to an array ref
      3. store each arrayref into an array

      modifying your code without munging it too much, I change to storing the array ref in $tlist[$tnum]; And then when we access from $tlist, we dereference into the array.

      The syntax you had @tlist[$i] was actually doing an array slice.

      print "\n\nThe Hash Table\n\n"; foreach $thread (keys %threads) { print "$thread: @{$threads{$thread}}\n"; } #this prints out lines like: #keyA: 2 6 8 #keyB: 3 5 10 14 18 #etc. # Convert hash table into arrays for Threads, with common index $tnum $tnum=0; foreach $thread (keys %threads) { $tsub[$tnum] = $thread; $tlist[$tnum] = $threads{$thread}; #store the array reference. $tsize[$tnum] = @{ $tlist[$tnum] }; $tnum++; } print "\n\nThe Thread Arrays\n\n"; for ($i=0;$i<$tnum ;$i++) { print "\n$tsub[$i], size=$tsize[$i], @{$tlist[$i]"; }
Re: hash of arrays to array of arrays
by hda (Chaplain) on Jul 16, 2009 at 20:56 UTC
    Hi,

    if your arrays are numeric go and check Perl Data Language. This is the most powerful way to perform multidimensional operations in Perl.

    Hope this helps.

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: perlquestion [id://780833]
Approved by Perlbotics
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others studying the Monastery: (7)
As of 2024-03-28 08:48 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found