my @unique_vault_list; @tapes_for_box1 = $unique_vault_list[0..19]; @tapes_for_box2 = $unique_vault_list[20..$#unique_vault_list];Neither subsequent array is giving me a list of at the most 20 elements as I would expect. Where am I going wrong? Thanks!
I recommend you read [id://525392] :). The short version is that you are geting the scalar range operator (scalar context) rather than the list you expected for a slice. The immediate fix is:
use strict; use warnings; my @unique_vault_list = (1..32); my @tapes_for_box1 = @unique_vault_list[0..19]; my @tapes_for_box2 = @unique_vault_list[20..$#unique_vault_list]; print "Box 1: @tapes_for_box1\n"; print "Box 2: @tapes_for_box2\n";
Prints:
Box 1: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 Box 2: 21 22 23 24 25 26 27 28 29 30 31 32
An alternative if you don't mind clobbering your original list (or making a copy of it) is:
use strict; use warnings; my @unique_vault_list = (1..32); my @tapes_for_box1 = splice @unique_vault_list, 0, 20; my @tapes_for_box2 = splice @unique_vault_list, 0, 20; print "Box 1: @tapes_for_box1\n"; print "Box 2: @tapes_for_box2\n";
Prints:
Box 1: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 Box 2: 21 22 23 24 25 26 27 28 29 30 31 32
@tapes_for_box1 = @unique_vault_list[0..19]; @tapes_for_box2 = @unique_vault_list[20..$#unique_vault_list];you are using slices, so you need to use @ instead of the singular $ prefix to your array 'unique_vault_list'
Chris
Other than the already suggested
@tapes_for_box1 = @unique_vault_list[0..19]; @tapes_for_box2 = @unique_vault_list[20..$#unique_vault_list];
you could use
@tapes_for_box1 = splice(@unique_vault_list, 0, 20); @tapes_for_box2 = @unique_vault_list;
which can be expanded into
my @tapes_by_box; push(@tapes_by_box, [ splice(@unique_vault_list, 0, 20) ]) while @unique_vault_list;
The difference is that splice removes the items from @unique_vault_list. (And it does so efficiently when removing from the start or end, as is the case here.)
What I want to do is grab the first block of 20 elements from the array and perform some task on them. Then I want to grab the second block of whatever number of elements is left (lets say there is 12 left) and perform a task on them.
And what will happen when your requirements change and you need, say, 13 elements instead of 20? You'll have to change your code so that 0..19 becomes 0..12, 20..32 becomes 13..25 and you'll have to add another iteration for the elements 26..$#unique_vault_list. That is partly addressed by the [doc://splice] solution but I think [cpan://List::MoreUtils]' natatime function would be better suited for this:
use List::MoreUtils qw/natatime/;
my @unique_vault_list = 0..31;
my $iter = natatime 20, @unique_vault_list;
while (my @cur = $iter->()) {
## now you have each group of 20 elements in @cur
print "@cur\n";
}
__END__
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
20 21 22 23 24 25 26 27 28 29 30 31
This way, you don't have to work with @tapes_for_box1, @tapes_for_box2 and maybe @tapes_for_box3...
--
David Serrano
perlmonks.org content © perlmonks.org and cdarke, Cristoforo, GrandFather, Hue-Bond, ikegami, jgiller, santonegro
prlmnks.org © 2006 edmund von der burg (eccles & toad)
v 0.03