in reply to Stack table columns with hash of arrays

ikegami's solution is simple and to the point. It's really the most elegant solution I see, but it does rely on the fact that your input data has no values repeated among the table columns. In other words, foo1 has '1', and '1' appears nowhere else in the table. That may be a perfectly good assumption, and may work just fine for you, in which case, stop reading now. ;)

If the numeric values in the table are non-unique, the solution doesn't work, because the hash used to transform the table is keyed off of the table's numeric values. And as we know, hash keys are unique.

So, I came up with an alternate solution, which is far less elegant, but not constrained by unique tabular data. The numeric fields may be non-unique.

use strict; use warnings; use feature qw(say); my %foos; # Grab the table and put it into a hash of arrays. while( my $line = <DATA> ) { chomp $line; my( $foo, @values ) = split /\s+/, $line; $foos{$foo} = \@values; } # Hang onto the foos as keys in sorted order. my @foo_keys = sort keys %foos; # Figure out how wide the table is (must be uniform across foos). my $last_col = $#{ $foos{ $foo_keys[0] } }; foreach my $col ( 0 .. $last_col ) { print map { "$_\t$foos{$_}->[$col]\n" } @foo_keys; } __DATA__ foo1 1 4 7 foo2 2 5 8 foo3 3 6 9

My solution takes a shortcut which is also based on an assumption that may not be true. My solution relies on all rows having the same number of columns. If that were not the case, you would have to track how many columns each row has, and iterate accordingly. That adds a little complexity that I didn't think was needed. But I mention it because it would need to be dealt with if your rows were not of uniform length.


Dave

Replies are listed 'Best First'.
Re^2: Stack table columns with hash of arrays
by robertkraus (Novice) on May 31, 2011 at 09:05 UTC
    Dear Dave! Great you posted this. In the meanwhile I was actually adjusting the previous solution to my real data and found out that ikegami's solution indeed 'only' fits my example, which I made up to convey what I am after. But not not my real data! Because yes, it ignores multiple occurrences of values. And it would sort and shuffle around not only the keys (which is what I need), but also the values (which is undesired). I was just about to prepare a post to explain what does, and what doesn't work. But thanks to you both! That was great help! Cheers, Rober
Re^2: Stack table columns with hash of arrays
by Anonymous Monk on May 31, 2011 at 12:05 UTC
    Dear Dave,  my $last_col = $#{ $foos{ $foo_keys[0] } }; brings -1. Where do I make a mistake? Thanks!

      When you're reading in the file, skip non-tabular (such as blank) lines.


      Dave

        Thank you Dave, it works now!