Beefy Boxes and Bandwidth Generously Provided by pair Networks
No such thing as a small change
 
PerlMonks  

Re: Manually incrementing @ array during for

by Fletch (Bishop)
on Mar 16, 2020 at 16:09 UTC ( [id://11114350]=note: print w/replies, xml ) Need Help??


in reply to Manually incrementing @ array during for

You need to get fancier in your parsing. You need to examine each line as it comes in, determine if it's a continuation (presuming leading whitespace indicates this, going from your example data) and (if not) append to the "current line". Once you're sure you have a full line, then process it and clear out the current line. Handwavy, vague outline:

my $current_line = q{}; while( defined( my $line = <> ) ) { chomp( $line ); if( $line =~ m{^ \s+ \w+ }x ) { $current_line .= $line; next; } else { _process_line( $current_line ); $current_line = $line; } } if( $current_line ) { _process_line( $current_line ); } sub _process_line { my( $line ) = $shift; ## do whatever . . . }

Update: Fuller example with sample data and fixing a bugglet first time through loop.

The cake is a lie.
The cake is a lie.
The cake is a lie.

Replies are listed 'Best First'.
Re^2: Manually incrementing @ array during for
by cniggeler (Sexton) on Mar 16, 2020 at 16:40 UTC
    Thank you for your prompt reply. I agree the steps necessary require more sophisticated parsing. I like the approach where a split data line is joined, then just process the entire line.

    However, this is part of a much bigger body of code, and I receive the already created @array, so I don't think I can shift since the @array may be used elsewhere.

    That being the case, do you think I should use an array index instead? Sort of a combination of yours and the previous reply. I could peek ahead to the next line and if it starts with blanks (or is not a keyword), I could then combine the next line to the current line as per your approach... Unless you say otherwise, I think I will go this route. Thanks again!

      Several other monks have been suggesting ways to handle this that end up modifying @array. If your part of the program receives a reference to @array, you can use the dclone method from the core module Storable to copy the array and then mangle the copy however you want.

      Adapted from the Storable POD:

      use Storable qw(dclone); # ... my $arrayref = dclone($provided_arrayref);

      As long as @array is small enough to copy, this should be very efficient; Storable is an XS module.

        If the array is an array of scalars (and none of the elements are references), of course, one can just do @copy = @original and it will work fine.

      Very similar approach in that case, just instead of reading lines from the file you walk the indexen instead. The concatenation and processing of entries is similar otherwise (my sample changes only 4 lines).

      The cake is a lie.
      The cake is a lie.
      The cake is a lie.

        Note that the body of this while-loop is equally well suited to the original for-loop implementation. The array is not changed.

        c:\@Work\Perl\monks>perl -wMstrict -MData::Dump -le "my @ra = ( 'keyword1 data1 data2 data3', 'keyword2 data1 data2 data3', ' data4 data5', ' data6', 'keyword1 data1 data2 data3 data4', 'keyword3 data1', ); ;; my $rx_continuation = qr{ \A \s+ \w }xms; ;; my $current_line; LINE: for my $line (@ra) { if ($line =~ $rx_continuation) { $current_line .= $line; next LINE; } ;; _process($current_line) if $current_line; $current_line = $line; } ;; _process($current_line) if $current_line; ;; dd \@ra ;; ;; sub _process { print qq{'$_[0]' ->}, map qq{ '$_'}, split ' ', $_[0]; } " 'keyword1 data1 data2 data3' -> 'keyword1' 'data1' 'data2' 'data3' 'keyword2 data1 data2 data3 data4 data5 data6' -> 'keyword2' 'da +ta1' 'data2' 'data3' 'data4' 'data5' 'data6' 'keyword1 data1 data2 data3 data4' -> 'keyword1' 'data1' 'data2' 'data +3' 'data4' 'keyword3 data1' -> 'keyword3' 'data1' [ "keyword1 data1 data2 data3", "keyword2 data1 data2 data3", " data4 data5", " data6", "keyword1 data1 data2 data3 data4", "keyword3 data1", ]


        Give a man a fish:  <%-{-{-{-<

Log In?
Username:
Password:

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

How do I use this?Last hourOther CB clients
Other Users?
Others studying the Monastery: (5)
As of 2024-04-20 00:05 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found