How can I iterate through nested arrays?

I created an array as follows

while (defined ($line = `<STDIN>`))

        {
        chomp ($line);
        push @stack,($line);
        }

      

each line has two numbers.

15 6
2  8

      

how to iterate over each element in each line?

i.e. I want to print

15
6
2
8

      

I understand something like

foreach (@{stack}) (@stack){

    print "?????
}  

      

This is where I got stuck.

+2


source to share


5 answers


See perldsc documentation . This is the Perl Data Structures Cookbook which has examples for working with arrays of arrays. From what you are doing, it looks like you don't need an array of arrays.

For your problem with two numbers per line and outputting one number per line, just turn the space into newlines:

 while( <> ) {
     s/\s+/\n/; # turn all whitespace runs into newlines
     print;     # it ready to print
     }

      

As of Perl 5.10, you can use a new character class \h

that only matches horizontal space:



 while( <> ) {
     s/\h+/\n/; # turn all horizontal whitespace runs into newlines
     print;     # it ready to print
     }

      

As a Perl one-liner, it's simple:

 % perl -pe 's/\h+/\n/' file.txt

      

+10


source


#!/usr/bin/perl

use strict;
use warnings;

while ( my $data = <DATA> ) {
    my @values = split ' ', $data;
    print $_, "\n" for @values;
}


__DATA__
15 6
2  8

      

Output:

C: \ Temp> h
15
6
2
8

Alternatively, if you want to save each line in @stack

and print later:

my @stack = map { [ split ] } grep { chomp; length } <DATA>;

      

The line above rips whatever comes from the file descriptor DATA

into a list of lines (because it <DATA>

happens in the context of a list). grep

chomps each line and filters by length after chomping (to avoid getting any trailing blank lines in the datafile - you can avoid this if there aren't any). Then it map

splits each line along spaces and then creates an anonymous array reference for each line. Finally, such array references are stored in each element @stack

. You can use the Data::Dumper

viewer @stack

to understand what's going on.

print join("\n", @$_), "\n" for @stack;

      



We now loop through each entry on the stack, playing each array in turn, and then concatenate the elements of each array with newlines to print one element per line.

Output:

C: \ Temp> h
15
6
2
8

Long way of writing essentially the same thing (with less memory consumption):

my @stack;

while ( my $line = <DATA> ) {
    last unless $line =~ /\S/;
    my @values = split ' ', $line;
    push @stack, \@values;
}

for my $ref ( @stack ) {
    print join("\n", @$ref), "\n";
}

      

Finally, if you want to do something other than printing all values, such as summing all numbers, you must store one value per element @stack

:

use List::Util qw( sum );

my @stack;

while ( my $line = <DATA> ) {
    last unless $line =~ /\S/;
    my @values = split ' ', $line;
    push @stack, @values;
}

printf "The sum is %d\n", sum @stack;

      

+8


source


#!/usr/bin/perl

while ($line = <STDIN>) {
    chomp ($line);
    push @stack, $line;
}

# prints each line
foreach $line (@stack) {
    print "$line\n";
}

# splits each line into items using ' ' as separator
# and prints the items
foreach $line (@stack) {
    @items = split / /, $line;

    foreach $item (@items) {
        print $item . "\n";
    }
}

      

0


source


I use "for" for "C" style loops and "foreach" for iterating over lists.

0


source


#!/usr/bin/perl

use strict;
use warnings;
open IN, "< read.txt" or
    die "Can't read in 'read.txt'!";

my $content = join '', <IN>;

while ($content =~ m`(\d+)`g) {
    print "$1\n";
}

      

0


source







All Articles