Beefy Boxes and Bandwidth Generously Provided by pair Networks
Keep It Simple, Stupid

foreach in array

by loop362 (Pilgrim)
on Jul 23, 2008 at 23:25 UTC ( #699721=perlquestion: print w/replies, xml ) Need Help??
loop362 has asked for the wisdom of the Perl Monks concerning the following question:

Aloha, I am trying to iterate through a simple array of 5 lines (read from a text file). I know the array always starts with 0. So when using the for each loop it skips 0. Why? This makes it leave out the first line, I only get 4 lines. I need to use PERL more often! I use BBEdit. I just opened my names.txt in Firefox also confirming 5 names. and added print scalar of @data.
foreach $name (@data) { print "$name"; }
#!/usr/bin/perl use strict; use warnings; my @data; my $name; open (JOE, "</Users/mrg/Desktop/names.txt") or die "No can!"; while (<JOE>) { @data = <JOE>; } foreach $name (@data) { print "$name"; }
This is names.txt
Joseph.Guillaume Fred.Flintsone Barney.Rubble George.Jetson ElRoy.Jetson
This is the Ouput:
Last login: Wed Jul 23 13:44:11 on ttyp1 Welcome to Darwin! G4-2:~ mrg$ /var/tmp/folders.507/Cleanup\ At\ Startup/test-238549606.0; exit Fred.Flintsone Barney.Rubble George.Jetson ElRoy.Jetsonlogout [Process completed]
Problem solved! by injunjoe Mahalo (Thank You)

Replies are listed 'Best First'.
Re: foreach in array
by injunjoel (Priest) on Jul 24, 2008 at 00:04 UTC
    Greetings, I would suspect its a problem with how you are reading the lines in... try this
    while(<JOE>){ push @data,$_; }
    rather than
    while(<JOE>){ @data = <JOE>; }
    I think the while is shifting off the first element and thus you are getting what is left in @data.

    "I do not feel obliged to believe that the same God who endowed us with sense, reason and intellect has intended us to forego their use." -Galileo

      ++injunjoel, I was going to point this (the double use of <JOE>) out if you hadn't.

Re: foreach in array
by broomduster (Priest) on Jul 24, 2008 at 00:20 UTC
    The "problem" here is that the diamond operator consumes one line of input. So the line

    while (<JOE>) {

    eats the first line of the input file, but doesn't save it anywhere. You either want just

    my @data = <JOE>;


    my @data; while (<JOE>) { push @data, $_; }

    and yes, yes, yes, always

    use strict; use warnings;

Re: foreach in array
by ikegami (Pope) on Jul 23, 2008 at 23:34 UTC

    You must be mistaken about the contents of your array. foreach doesn't skip elements.

    my @data = qw( foo bar baz moo mar ); print("1st - 0 - $data[0]\n"); print("5th - 4 - $data[4]\n"); print("\n"); foreach $name (@data) { print "$name\n"; }
    1st - 0 - foo 5th - 4 - mar foo bar baz moo mar

    A good way of determining the contents of an arbitrarily complex data structure (or a simple array) is to use Data::Dumper.

    use Data::Dumper; my @data = qw( foo bar baz moo mar ); print(Dumper(\@data));
    $VAR1 = [ 'foo', 'bar', 'baz', 'moo', 'mar' ];

    By the way, the language is called "Perl", not "PERL".

Re: foreach in array
by Joost (Canon) on Jul 23, 2008 at 23:35 UTC
Re: foreach in array
by GrandFather (Sage) on Jul 23, 2008 at 23:40 UTC

    Indeed you do! For a start always use strictures (use strict; use warnings; - see The strictures, according to Seuss).

    You don't need to interpolate the string in print.

    If all you are doing is printing each "line" from @data then you can:

    use strict; use warnings; my @data = ...; print for @data;

    foreach is a synonym for for.

    The code you show will print all the contents of @data. If it doesn't print what you expected than @data doesn't contain what you expected.

    Perl is environmentally friendly - it saves trees
Re: foreach in array
by toolic (Bishop) on Jul 23, 2008 at 23:52 UTC
    In addition to the advice you have already received, a quick way to verify that the number of elements in an array is what you expect it to be is to use scalar:
    print scalar @data, "\n";
Re: foreach in array
by linuxer (Curate) on Jul 23, 2008 at 23:35 UTC

    check if @data really contains the expected number of elements.

    make sure that your printed output is distinct (maybe empty string or undef in element).

    make sure you use strict and warnings in your scripts

    print "elements in \@data: ", scalar( @data ), $/; foreach my $name ( @data ) { print "<$name>"; }

    update: quoted @. Thanks GrandFather

      You probably meant to quote the @:

      print "elements in \@data: ", scalar( @data ), $/;

      Perl is environmentally friendly - it saves trees

Log In?

What's my password?
Create A New User
Node Status?
node history
Node Type: perlquestion [id://699721]
Approved by Joost
and all is quiet...

How do I use this? | Other CB clients
Other Users?
Others meditating upon the Monastery: (5)
As of 2017-01-22 11:07 GMT
Find Nodes?
    Voting Booth?
    Do you watch meteor showers?

    Results (187 votes). Check out past polls.