perlguru22 has asked for the
wisdom of the Perl Monks concerning the following question:
Hey,guys I have to create the subroutine that will take the even and odd numbers from an array and print them out but I Haven't been able to combine the 2 into 1 this is what I have
sub even
{
my @a = @_;
foreach $number(@a)
{
if($number%2==1)
{
$number = $_;
}
print "$number";
}
print " = Even numbers\n";
}
sub odd
{
my @a = @_;
foreach my$number (@a)
{
if($number%2==0)
{
$number = $_;
}
print "$number";
}
print "= odd numbers\n";
}
I know there's an easier way to do it but I always complicate my program I would appreciate any help I can get.
Re: Subroutine Even/Odd by tobyink (Abbot) on Oct 04, 2012 at 07:36 UTC 
if($number%2==0)
{
$number = $_;
}
print "$number";
It works because $_ is initially undef and you never assign to it. It's incredibly fragile though.
Here's how I'd do it...
use 5.010;
use List::MoreUtils qw(part);
my $numbers = [ 1 .. 10, 211, 1000 ];
my ($evens, $odds) = part { $_ % 2 } @$numbers;
say "Even numbers: ";
say $_ for @$evens;
say "Odd numbers: ";
say $_ for @$odds;
perl E'sub Monkey::do{say$_,for@_,do{($monkey=[caller(0)]>[3])=~s{::}{ }and$monkey}}"Monkey say">Monkey::do'
 [reply] [d/l] [select] 
Re: Subroutine Even/Odd by johngg (Abbot) on Oct 04, 2012 at 08:11 UTC 
$ perl Mstrict Mwarnings E '
> my( @odds, @evens );
> push @{ $_ % 2 ? \ @odds : \ @evens }, $_ for 1 .. 10;
> say qq{ Odds: @odds};
> say qq{Evens: @evens};'
Odds: 1 3 5 7 9
Evens: 2 4 6 8 10
$
I hope this is of interest.
Update: Documentation link corrected, thanks choroba :)
 [reply] [d/l] 
Re: Subroutine Even/Odd by 2teez (Priest) on Oct 04, 2012 at 08:16 UTC 
"..I have to create the subroutine that will take the even and odd numbers from an array.."
A good compact solution has been showed by tobyink. However, you might find the following also useful:
use warnings;
use strict;
my $numbers = [ 1 .. 10 ];
print even($numbers); ## call even number generator subroutine
print $/;
print odd($numbers); ## call odd number generator subroutine
print $/;
## call combined even and odd number generator subroutine
my %even_n_odd_numbers = %{ even_odd($numbers) };
for ( keys %even_n_odd_numbers ) {
print $_, " ", join " ", @{ $even_n_odd_numbers{$_} }, $/;
}
sub even {
my ($numbers) = @_;
my @even_numbers;
for (@$numbers) {
push @even_numbers, $_ if $_ % 2 == 0;
}
return @even_numbers if wantarray;
}
sub odd {
my ($numbers) = @_;
my @odd_numbers;
for (@$numbers) {
push @odd_numbers, $_ if $_ % 2 == 1;
}
return @odd_numbers if wantarray;
}
sub even_odd {
my ($numbers) = @_;
my %even_odd = ( 'even' => undef, 'odd' => undef, );
for (@$numbers) {
if ( $_ % 2 == 0 ) {
push @{ $even_odd{'even'} }, $_;
}
else {
push @{ $even_odd{'odd'} }, $_;
}
}
return \%even_odd;
}
The combined subroutine is a lot better, because you don't have to repeat codes lines like one did in two different subroutines ( sub even{...} and sub odd{...}) having just only one line that is different from one another.
If you tell me, I'll forget.
If you show me, I'll remember.
if you involve me, I'll understand.
 Author unknown to me
 [reply] [d/l] 
Re: Subroutine Even/Odd by clueless newbie (Hermit) on Oct 04, 2012 at 14:32 UTC 
#!/usr/bin/perl
use strict;
use warnings;
# Effect a "join" with ", "
local $"=', ';#"
# Use the baby cart so we can call even / odd within quotes to exploit
+ $"
print "@{[even(1,2,3,4)]} are even\n while @{[odd(1,2,3,4)]} are odd\n
+";
exit;
# Note the use of prototypes so we can pass the list and the desired r
+emainder without flattening
sub EvenOrOdd (\@$) {
my ($numbers,$remainder)=@_;
return grep { $_ % 2 == $remainder } @$numbers;
};
sub even {
EvenOrOdd(@_,0);
};
sub odd {
EvenOrOdd(@_,1);
};
 [reply] [d/l] 
Re: Subroutine Even/Odd by marquezc329 (Scribe) on Oct 04, 2012 at 18:20 UTC 
Here's what I came up with.
#!/usr/bin/perl
use strict;
use warnings;
sub num
{
my $array = shift;
my $func = shift;
return grep {$_%2==0} @$array if ($func eq 'even');
return grep {$_%2!=0} @$array if ($func eq 'odd');
}
my @a = 1..10;
my @b = (447..460, 2000..2012);
print num(\@a, 'even'), "\n";
print num(\@b, 'odd'), "\n";
I'm a beginner so please inform me if this is an inefficient/misguided way of accomplishing this.  [reply] [d/l] 

