2

I have created an array as follows

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

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

each line has two numbers.

15 6
2  8

how do iterate over each item in each line?

i.e. I want to print

15
6
2
8

I understand it's something like

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

    print "?????
}  

This is where I am stuck.

3
  • 4
    Don't understand how what you want to print is different from what you've got. Also, those backticks don't look right. Commented Oct 15, 2009 at 10:33
  • 1
    Ditto on the backtics. Remove them and use while (my $line = <>). Commented Oct 15, 2009 at 12:07
  • while(my $line=<>) gets automatically converted to while(defined(my $line=<>)) Commented Oct 16, 2009 at 19:28

5 Answers 5

10

See the perldsc documentation. That's the Perl Data Structures Cookbook, which has examples for dealing with arrays of arrays. From what you're doing though, it doesn't look like you need an array of arrays.

For your problem of taking two numbers per line and outputting one number per line, just turn the whitespace into newlines:

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

With Perl 5.10, you can use the new \h character class that matches only horizontal whitespace:

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

As a Perl one-liner, that's just:

 % perl -pe 's/\h+/\n/' file.txt
Sign up to request clarification or add additional context in comments.

Comments

8
#!/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 store each line in @stack and print out later:

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

The line above slurps everything coming from the DATA filehandle into a list of lines (because <DATA> happens in list context). The grep chomps each line and filters by length after chomping (to avoid getting any trailing empty lines in the data file -- you can avoid it if there are none). The map then splits each line along spaces, and then creates an anonymous array reference for each line. Finally, such array references are stored in each element of @stack. You might want to use Data::Dumper to look at @stack to understand what's going on.

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

Now, we look over each entry in stack, dereferencing each array in turn, then joining the elements of each array with newlines to print one element per line.

Output:

C:\Temp> h
15
6
2
8

The long way of writing essentially the same thing (with less memory consumption) would be:

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 wanted do something other than printing all values, say, sum all the numbers, you should store one value per element of @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;

Comments

0
#!/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";
    }
}

8 Comments

Does the final 'for' need to be 'foreach' also?
Foreach would have been more easy to understand for sure, from perldoc perlsyn: > The "foreach" keyword is actually a synonym for the "for" keyword, so you can use "foreach" for readability or "for" for brevity.
foreach and for behave identically. Many perlers prefer to use for exclusively.
I used to be a big fan of foreach. Now I have forgotten that it even exists. (Or maybe I've just "for" that it even exists...)
How to do what? You're code is just what I did, with just a lot more work. No one has even shown a single reference in any code yet.
|
0

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

3 Comments

There is no need to make such an artificial distinction between the two.
There is no need, but that's what I do too. It's just syntactic sugar.
I use for for both. C style loops will be written with loop in Perl6, and foreach will get renamed to for
0
#!/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";
}

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.