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

Hello Monks - Continuing on the path of enlightment, I'm trying to work with a complex data structure. I have a hash that contains n keys - n varies depending on the input. Each value is an array and each array has the same number of elements. For example,
%HofA{0} = 1;;;;;;; ;;;;;;;; ;;;;;;;; ;;LINE;;SVC;LINE;ACCT;VIEW; %HofA{1} = 1;; ;;; ;;; ;LINE;; %HofA{2} = 1;;;;; ;;;;;; ;;;LAST;;; ;UPDT;SRCE;UPDT;UPDT;WORK;
I am trying to join each element in each of the arrays & then print the joined line to a file.

Example 1: Joining the first element in all arrays should produce:

1;;;;;;;1;;1;;;;;
Example 2: Joining the last element in the sample data in all arrays should produce:
;;LINE;;SVC;LINE;ACCT;VIEW;;LINE;;;UPDT;SRCE;UPDT;UPDT;WORK;
I've found many references and code snippets when the number of keys is known, but I'm not that lucky. Since the number of keys depends on the input, I suspect an eval statement is in my future. I've read perldsc, perlfunc & scanned the ref/tut and Q&A and have no clue how to start. Could one of you wizards point me in the correct direction? Thanks.

Replies are listed 'Best First'.
Re: stumped on a complex data structure
by ikegami (Patriarch) on Nov 15, 2004 at 19:12 UTC

    Input:

    my @keys = sort keys %HoA; my $num_elements = @{$HoA{$keys[0]}}; for (my $i=0; $i<$num_elements; $i++) { print FILE join('', map { $HoA{$_}[$i] } @keys), $/; }

    Output:

    MapCar and MapCarU from Algorithm::Loops could be used as an alternative, but it would be overkill.

Re: stumped on a complex data structure
by jimbojones (Friar) on Nov 15, 2004 at 19:39 UTC
    Based on the fact that your hash keys are numeric, and that you depend on the output being ordered, I think you need an Array of Arrays

    my $output = ""; my @AofA = ( [ '1;;;;;;;', ';;;;;;;;', ';;;;;;;;', ';;LINE;;SVC;LINE;ACCT;VIEW;' ], [ '1;;', ';;;', ';;;', ';LINE;;' ], [ '1;;;;;', ';;;;;;', ';;;LAST;;;', ';UPDT;SRCE;UPDT;UPDT;WORK;' ] ); foreach my $array_ref ( @AofA ) { $output .= $array_ref->[3]; } print "$output\n";
    output is

    ;;LINE;;SVC;LINE;ACCT;VIEW;;LINE;;;UPDT;SRCE;UPDT;UPDT;WORK;

    If you do want a hash, then you will have to sort the hash keys to get teh output in the order you want

    - j
Re: stumped on a complex data structure
by BrowserUk (Patriarch) on Nov 15, 2004 at 19:39 UTC

    UPDATE: Ignore this. I misread the question. (The question at the bottom's still valid though).

    my %HoA = ( 0=>[ 1, 2, 3 ], 1=>[ 4, 5, 6 ], 2=>[ 7, 8, 9 ] ); print join'', map @{ $HoA{ $_ } },sort{$a<=>$b} keys %HoA; 123456789

    One point. If your hash keys are consecutive integers starting from 0, why use a HoA and not a AoA?


    Examine what is said, not who speaks.
    "Efficiency is intelligent laziness." -David Dunham
    "Think for yourself!" - Abigail        "Time is a poor substitute for thought"--theorbtwo
    "Memory, processor, disk in that order on the hardware side. Algorithm, algorithm, algorithm on the code side." - tachyon
      Shouldn't the output be 147258369?

        Updated. Thanks.


        Examine what is said, not who speaks.
        "Efficiency is intelligent laziness." -David Dunham
        "Think for yourself!" - Abigail        "Time is a poor substitute for thought"--theorbtwo
        "Memory, processor, disk in that order on the hardware side. Algorithm, algorithm, algorithm on the code side." - tachyon
        Yes, this is what I'm looking for. Haven't got it working yet, but have dim glimmer on how this stuff works. am starting to understand how to bump thru this data structure.
Re: stumped on a complex data structure
by TedPride (Priest) on Nov 16, 2004 at 15:24 UTC
    use strict; use warnings; my %HofA = ( 0 => [ '1;;;;;;;', ';;;;;;;;', ';;;;;;;;', ';;LINE;;SVC;LINE;ACCT;VIEW;', ], 1 => [ '1;;', ';;;', ';;;', ';LINE;;', ], 2 => [ '1;;;;;', ';;;;;;', ';;;LAST;;;', ';UPDT;SRCE;UPDT;UPDT;WORK;', ], ); my @out; for (sort {$a <=> $b} keys %HofA) { my $c; for (@{$HofA{$_}}) { $out[$c++] .= $_; } } print "$_\n" for (@out);
    The advantage of this method is it only requires one pass through the hash, and it works with variable numbers of array slots. Note that I'm sorting on numerical comparison, since the example given had numerical keys and a straight sort would mess up the order.