in reply to Array in Array

Abigail-II's solution fails for the last string because of the empty entry E. Here's another way to parse this:

my @accounts = ( "A x1 B y1 C z1 D v1 E w1 F", "A x2 B y2 C zzz2 D v2 E w2 F", "A x3 B y3 C z3 D v3 E w3 F", "A x4 B y4 C z4 D v4 E wwww4 F", "A x5 B y5 C z5 D v5 E w5 F", "A x6 B y6 C z6 D v6 E F", ); # Transform @accounts in place for (@accounts) { tr/ //d; # get rid of those confusing spaces my @acct = split /([A-F])/; # use the tags shift @acct; # get rid of the undef pre-A entry... pop @acct; # ... and the 'F' my %stuff = (@acct); # hash what's left $_ = [@stuff{'A'..'E'}]; # keep ordered values } { local $" = "\t"; print "|@$_|", $/ for @accounts; } __END__ |x1 y1 z1 v1 w1| |x2 y2 zzz2 v2 w2| |x3 y3 z3 v3 w3| |x4 y4 z4 v4 wwww4| |x5 y5 z5 v5 w5| |x6 y6 z6 v6 |
The transformation of @accounts could be shortened a lot, but I wanted to show it step-by-step for clarity. Your data format is not of the handiest.

After Compline,
Zaxo

Replies are listed 'Best First'.
Re: Re: Array in Array
by nylon (Acolyte) on Oct 07, 2003 at 06:01 UTC
    Dear all,

    I have to study all of this. This is for me new stuff.
    Thanks for all the help. :-) :-) :-)
    Nylon
      PS: The border are not always [A..B], it could be  [A G L Z *  .. boe ..] etc etc.
      I used the  [A..B] as an example.
      Sorry that I was not clear.
      Nylon
        Given your clarifications, this change to Abigail's code may work better for you:
        #!/your/perl/here use strict; use warnings; my @accounts = ("A x1 B y1 C z1 D v1 E w1 F", "A x2 B y2 C zzz2 D v2 E w2 F", "A x3 B y3 C z3 D v3 E w3 F", "A x4 B y4 C D v4 E wwww4 F", # note change to C..D "A x5 B y5 C z5 D v5 E w5 F", "A x6 B y6 C z6 D v6 E F"); my @fields = ("A", "B", "C", "D", "E", "F"); my $regex = join '\s+(\w*)\s+', @fields; my @accounts_2 = map {[/$regex/]} @accounts; __END__
        The code map {[/$regex/]} @accounts creates an anonymous array for each element of @accounts.

        And with the debugger:
        DB<3> x @accounts_2 0 ARRAY(0x1ca7364) 0 'x1' 1 'y1' 2 'z1' 3 'v1' 4 'w1' 1 ARRAY(0x1ca2b30) 0 'x2' 1 'y2' 2 'zzz2' 3 'v2' 4 'w2' 2 ARRAY(0x1cbe7cc) 0 'x3' 1 'y3' 2 'z3' 3 'v3' 4 'w3' 3 ARRAY(0x1cbe88c) 0 'x4' 1 'y4' 2 '' # reflects data change above 3 'v4' 4 'wwww4' 4 ARRAY(0x1cbf97c) 0 'x5' 1 'y5' 2 'z5' 3 'v5' 4 'w5' 5 ARRAY(0x1cbe8bc) 0 'x6' 1 'y6' 2 'z6' 3 'v6' 4 ''
        Note that if the stuff between field markers resembles the field markers, this won't work. Also, for pathological inputs, backtracking is a real issue.

        -QM
      To my regret it is not working.
      The script needs to use the array (@fields) (and not the  [A..F] ) as separator. I got empty results. :-(
      It looked so simple in the beginning (when I started the script) but for a newbie it is not.
      Thx,
      Nylon
        You don't say what is not working. Anyway, here is a different way to do it:
        @fields = ("A", "B", "C", "D", "E", "F"); $splitem = join '\s*(\S*)\s*', map quotemeta $_, @fields; print $splitem; for my $rec (@accounts) { my @rowdata = $rec =~ /^$splitem\z/o or warn("misparsed $rec"), ne +xt; push @accounts_2, \@rowdata; } for ($j = 0; $j < @accounts_2; ++$j) { for ($i = 0; $i < @{$accounts_2[$j]}; ++$i) { print ("\$accounts_2[$j][$i] = $accounts_2[$j][$i]\n"); } }