extract every other element from an array

K

kg.google

I iterate over odd/even index elements from @array with the code below.
This is the inner most piece of a huge loop, so if there is a more
efficient way, it will make a big difference ;-) Is there a better
way? (relative element order must be maintained)


my $i = 0; # 0=odd, 1=even
foreach(grep $i++ % 2, @array)
{
}


By the way, @array is usually small (2 or 4 elements)
thanks,
Kiriakos
 
B

Brian Wakem

I iterate over odd/even index elements from @array with the code below.
This is the inner most piece of a huge loop, so if there is a more
efficient way, it will make a big difference ;-) Is there a better
way? (relative element order must be maintained)


my $i = 0; # 0=odd, 1=even
foreach(grep $i++ % 2, @array)
{
}


By the way, @array is usually small (2 or 4 elements)
thanks,
Kiriakos



How about:-

while(@array) {
shift @array;
my $element = shift @array;
}


But if you need to keep @array intact then you'll need to copy it first.
 
A

Anno Siegel

I iterate over odd/even index elements from @array with the code below.
This is the inner most piece of a huge loop, so if there is a more
efficient way, it will make a big difference ;-) Is there a better
way? (relative element order must be maintained)


my $i = 0; # 0=odd, 1=even
foreach(grep $i++ % 2, @array)
{
}

Looks fine to me, efficiency-wise. An alternative:

for ( @array[ map 2*$_, 0 .. @array/2] ) {
}

Anno
 
X

xhoster

I iterate over odd/even index elements from @array with the code below.
This is the inner most piece of a huge loop, so if there is a more
efficient way, it will make a big difference ;-) Is there a better
way? (relative element order must be maintained)


my $i = 0; # 0=odd, 1=even
foreach(grep $i++ % 2, @array)
{
}

Looks fine to me, efficiency-wise. An alternative:

for ( @array[ map 2*$_, 0 .. @array/2] ) {

You probably want "$#array/2"

Xho
 
A

Anno Siegel

I iterate over odd/even index elements from @array with the code below.
This is the inner most piece of a huge loop, so if there is a more
efficient way, it will make a big difference ;-) Is there a better
way? (relative element order must be maintained)


my $i = 0; # 0=odd, 1=even
foreach(grep $i++ % 2, @array)
{
}

Looks fine to me, efficiency-wise. An alternative:

for ( @array[ map 2*$_, 0 .. @array/2] ) {

You probably want "$#array/2"

You're right, thanks. I did test *something*, will take another look
tonight.

Anno
 
M

Mark A

I iterate over odd/even index elements from @array with the code below.
This is the inner most piece of a huge loop, so if there is a more
efficient way, it will make a big difference ;-) Is there a better
way? (relative element order must be maintained)


my $i = 0; # 0=odd, 1=even
foreach(grep $i++ % 2, @array)
{
}

my $i = 1;
foreach (@array) {
if($i ^= 1) {

}
}
 
J

John W. Krahn

I iterate over odd/even index elements from @array with the code below.
This is the inner most piece of a huge loop, so if there is a more
efficient way, it will make a big difference ;-) Is there a better
way? (relative element order must be maintained)


my $i = 0; # 0=odd, 1=even
foreach(grep $i++ % 2, @array)
{
}


By the way, @array is usually small (2 or 4 elements)

You could use a C style for loop.

for ( my $i = 0; $i < @array; $i += 2 ) {
$array[ $i ] = something();
}



John
 
J

Jürgen Exner

I iterate over odd/even index elements from @array with the code
below. This is the inner most piece of a huge loop, so if there is a
more efficient way, it will make a big difference ;-) Is there a
better way?

Don't know if better, but this will work, too:

use strict; use warnings;
my @mylist=("one", "two", "three", "four", "five", "six");
my %foo = @mylist;
print keys(%foo);

(relative element order must be maintained)

Unfortunately the hash does not preserve the order :-(

jue
 
P

Paul Lalli

Jürgen Exner said:
Don't know if better, but this will work, too:

use strict; use warnings;
my @mylist=("one", "two", "three", "four", "five", "six");
my %foo = @mylist;
print keys(%foo);


Unfortunately the hash does not preserve the order :-(

It will also fail if any of the "keys" are duplicates.
use strict;
use warnings;
my @mylist = (qw/alpha one beta two alpha 1 gamma 3/);
my %foo = @mylist;
print keys (%foo);
__END__
gammabetaalpha
 
K

kg.google

Thanks for all the (clever) responses.

I really liked @array[ map 2*$_, 0 .. @array/2].

But none are actually faster. I thought about it, and then it came to
me that the odd (or even) index values don't need to be calculated each
time because I am not dealing with random @array's - I iterate over a
relatively small set of arrays (array refs actually) so, I can
precalculate and store the indices based on array legths outside the
inner loop. This improved efficiency by around 10%. Not bad!

thx,
Kiriakos
 
K

kg.google

Oops, Xho is right, the correct ways are:

@array[ map 2*$_, 0 .. $#array/2] # even indices
@array[ map 2*$_ + 1, 0 .. $#array/2] # odd indices
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,755
Messages
2,569,536
Members
45,020
Latest member
GenesisGai

Latest Threads

Top