LinuxQuestions.org
Share your knowledge at the LQ Wiki.
Home Forums Tutorials Articles Register
Go Back   LinuxQuestions.org > Forums > Non-*NIX Forums > Programming
User Name
Password
Programming This forum is for all programming questions.
The question does not have to be directly related to Linux and any language is fair game.

Notices


Reply
  Search this Thread
Old 03-24-2008, 03:16 AM   #1
hottdogg
Member
 
Registered: Aug 2004
Distribution: opensuse ,debian/ubuntu
Posts: 222

Rep: Reputation: 30
how to access just some part of array in perl?


I'm new in perl...
How to access just some part of array in perl using the index WITHOUT c-style for loop ?
is it possible ?
For example..
Code:
#want to print 11-25
my @testAr=(6 .. 40);
my %i=5; #expect to be the starting index
 
Old 03-24-2008, 05:37 AM   #2
exscape
Member
 
Registered: Aug 2007
Location: Sweden
Distribution: OS X, Gentoo, FreeBSD
Posts: 82

Rep: Reputation: 15
my @testAr = 6 .. 40;
for my $num (@testAr[5..19]) {
print "$num\n";
}

11
12
13
14
15
16
17
18
19
20
21
22
23
24
25

 
Old 03-24-2008, 08:58 AM   #3
hottdogg
Member
 
Registered: Aug 2004
Distribution: opensuse ,debian/ubuntu
Posts: 222

Original Poster
Rep: Reputation: 30
aaah!! ic....
*noticing index range inside square bracket at the for statement*

okay,tnx so much but what I mean is like accessing from
array not just printing... Hmm how to say it...
well, here's another example.

Using c-style for loop
Code:
#!/usr/bin/perl
#printing only even number from an array

my @testAr=(6 .. 40);

for (my $i=0; $i<=$#testAr;$i++ )
{
 if($testAr[$i]%2 == 0) {
    print "$testAr[$i]\n";
 }
}
Is the code above can be construct with perl's simple for loop ?
if it's not possible it's okay by me. Just want to see how much further perl can stay away from c...

I ask this because I'm trying to embrace more perlish style of perl code ... instead of C-ish perl code .Btw,my first prog lang is c so it's kinda hard for me to eliminate some c habit.
 
Old 03-24-2008, 09:27 AM   #4
exscape
Member
 
Registered: Aug 2007
Location: Sweden
Distribution: OS X, Gentoo, FreeBSD
Posts: 82

Rep: Reputation: 15
Quote:
Originally Posted by hottdogg View Post
Using c-style for loop
Code:
#!/usr/bin/perl
#printing only even number from an array

my @testAr=(6 .. 40);

for (my $i=0; $i<=$#testAr;$i++ )
{
 if($testAr[$i]%2 == 0) {
    print "$testAr[$i]\n";
 }
}
Enter grep!
Code:
my @testAr=(6..40);
my @even = grep {$_ % 2 == 0} @testAr;
print "$_\n" for @even;

### OR ###

my @testAr=(6..40);
print "$_\n" for grep {$_ % 2 == 0} @testAr;
 
Old 03-24-2008, 07:53 PM   #5
chrism01
LQ Guru
 
Registered: Aug 2004
Location: Sydney
Distribution: Rocky 9.2
Posts: 18,359

Rep: Reputation: 2751Reputation: 2751Reputation: 2751Reputation: 2751Reputation: 2751Reputation: 2751Reputation: 2751Reputation: 2751Reputation: 2751Reputation: 2751Reputation: 2751
Put it this way, if you've specified an array, you can then access any element by num eg $arr[$n], without a loop, but you
need to be sure the array has a value at that index, or use the 'defined()' fn http://perldoc.perl.org/functions/defined.html.
HTH
 
Old 03-24-2008, 09:51 PM   #6
hottdogg
Member
 
Registered: Aug 2004
Distribution: opensuse ,debian/ubuntu
Posts: 222

Original Poster
Rep: Reputation: 30
Quote:
Originally Posted by exscape View Post
Enter grep!
Code:
my @testAr=(6..40);
my @even = grep {$_ % 2 == 0} @testAr;
print "$_\n" for @even;

### OR ###

my @testAr=(6..40);
print "$_\n" for grep {$_ % 2 == 0} @testAr;
hey..i didn't think of that...
hah...definitely this is more perlish but still readable
getting more enlightment..

Tnx a lot guys.
 
Old 03-25-2008, 07:31 AM   #7
Telemachos
Member
 
Registered: May 2007
Distribution: Debian
Posts: 754

Rep: Reputation: 60
Obviously, TMTOWTDI applies here, but the Perl FAQ recommends not using grep just to print. It is still a Perl-ish idiom - which is why the FAQ mentions it, I think: trying to discourage a bad habit.
Quote:
Originally Posted by Perl FAQ
What's wrong with using grep in a void context?

The problem is that grep builds a return list, regardless of the context. This means you're making Perl go to the trouble of building a list that you then just throw away. If the list is large, you waste both time and space. If your intent is to iterate over the list, then use a for loop for this purpose.

In perls older than 5.8.1, map suffers from this problem as well. But since 5.8.1, this has been fixed, and map is context aware - in void context, no lists are constructed.
My sense is that true for loops are avoided in Perl and foreach loops are used instead. (The trick there is that you can write for even when you mean foreach. The interpreter figures it out based on the syntax of the loop.) So for your original question - you wanted to start at 11 - and your follow up - you only want even numbers, I think an array slice @array[x..y] and a foreach loop with an if is the way to go:
Code:
#!/usr/bin/perl
use strict;
use warnings;


my @testAr = 6 .. 40;
for my $num (@testAr[5..19]) {
    if (($num % 2) == 0 ) {
        print "$num\n";
    }
}
But I'm still learning Perl myself, so maybe I have this all wrong.

Edit - if you are really curious (and bored), check this huge thread on whether or not to add a warning in Perl for the use of grep and map in a void context: http://www.nntp.perl.org/group/perl....msg131922.html

Last edited by Telemachos; 03-25-2008 at 07:45 AM. Reason: Added Perl5.porters link
 
Old 03-25-2008, 06:41 PM   #8
osor
HCL Maintainer
 
Registered: Jan 2006
Distribution: (H)LFS, Gentoo
Posts: 2,450

Rep: Reputation: 78
Quote:
Originally Posted by Telemachos View Post
Obviously, TMTOWTDI applies here, but the Perl FAQ recommends not using grep just to print.
That’s all well and good, but exscape did not use grep in void context (the returned list is used as the argument of the for loop).
 
Old 03-25-2008, 07:29 PM   #9
Telemachos
Member
 
Registered: May 2007
Distribution: Debian
Posts: 754

Rep: Reputation: 60
Quote:
Originally Posted by osor View Post
That’s all well and good, but exscape did not use grep in void context (the returned list is used as the argument of the for loop).
Hmm, I see what you mean but I'm still not sure. He created a new list, merely to iterate over it in the print statement, and then he threw the list out. My understanding of the FAQ is that this is exactly what they mean when they say, "This means you're making Perl go to the trouble of building a list that you then just throw away. If the list is large, you waste both time and space. If your intent is to iterate over the list, then use a for loop for this purpose." I'm not trying to be difficult (though maybe I'm being dense), but why isn't a slice + test more efficient here?
 
Old 03-25-2008, 09:02 PM   #10
osor
HCL Maintainer
 
Registered: Jan 2006
Distribution: (H)LFS, Gentoo
Posts: 2,450

Rep: Reputation: 78
Quote:
Originally Posted by Telemachos View Post
Hmm, I see what you mean but I'm still not sure. He created a new list, merely to iterate over it in the print statement, and then he threw the list out.
I guess you’re right. But you don’t necessarily have to throw out the list (I think there’s a trade-off between the number of function calls and unnecessary array duplication):
Code:
#!/usr/bin/perl
use strict;
use warnings;

my @testAr = 6 .. 40;

$,="\n";
print grep($_ % 2 == 0, @testAr), "";
Alternatively, you could do (the somewhat harder to read, but works if you use something other than print which takes only a single scalar argument):
Code:
#!/usr/bin/perl
use strict;
use warnings;

my @testAr = 6 .. 40;

$"="\n";
print "@{[grep($_ % 2 == 0,@testAr)]}\n";
In general, the benefit (or real power) of using grep is that it can easily be linked to other grep or map (or sort) calls. You don’t see it in this example, however.

Last edited by osor; 03-25-2008 at 09:14 PM. Reason: add alternative that I thought of later
 
  


Reply



Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is Off
HTML code is Off



Similar Threads
Thread Thread Starter Forum Replies Last Post
perl + @INC array Ateo Programming 0 01-22-2007 01:38 PM
[Perl] array in scalar noir911 Programming 2 12-10-2006 04:52 PM
Accessing perl array rjcrews Programming 5 11-08-2006 07:16 PM
Perl Array Sorting craig467 Programming 8 10-02-2006 05:32 AM
PERL: Size of an array of an Array inspleak Programming 2 03-10-2004 02:24 PM

LinuxQuestions.org > Forums > Non-*NIX Forums > Programming

All times are GMT -5. The time now is 03:29 PM.

Main Menu
Advertisement
My LQ
Write for LQ
LinuxQuestions.org is looking for people interested in writing Editorials, Articles, Reviews, and more. If you'd like to contribute content, let us know.
Main Menu
Syndicate
RSS1  Latest Threads
RSS1  LQ News
Twitter: @linuxquestions
Open Source Consulting | Domain Registration