1: #!/usr/bin/perl -w
2: #
3: # Q: Perl need iterator? That's unpossible!
4: # A: Have you ever had to iterate on multiple list values at once? One
5: # often resorts to numeric indexing to solve this problem. Shift and splice
6: # is another WTDI, but only if you don't mind eating away at your original
7: # list. Think of the iterator as a non-mutating splice.
8: #
9: # iterstart ARRAY VARIABLE
10: # iterstart ARRAY
11: # Sets up iteration for a given array, with the iterator variable
12: # specified. Must be called before any of the other functions.
13: #
14: # iter NUM ARRAY
15: # iter NUM
16: # iter
17: # Iterates through and returns a list of next NUM elements for the
18: # active or specified array. A negative NUM acts as an index from the
19: # end of the array. When NUM is unspecified, it is defaulted as 1.
20: #
21: # iterend ARRAY
22: # iterend
23: # End iteration for active or specified array. Not usually
24: # needed.
25: #
26: use strict;
27: {
28: my (%listpos, $lref);
29:
30: sub iterstart (\@) {
31: $lref = shift;
32: $listpos{$lref} = 0;
33: }
34:
35: sub iter (;$\@) {
36: my $num = shift || 1;
37: $lref = shift if @_;
38: return if not exists $listpos{$lref};
39: my $i = $listpos{$lref};
40: my $j = $num >= 0 ? $i + $num - 1: $#$lref + $num + 1;
41: if ($j < $#$lref) {
42: $listpos{$lref} = $j + 1;
43: }
44: else {
45: delete $listpos{$lref};
46: $j = $#$lref;
47: }
48: @$lref[$i..$j];
49: }
50:
51: sub iterend (;\@) {
52: delete $listpos{shift || $lref}
53: }
54: }
55:
56: ############ EXAMPLES ############
57:
58: use Data::Dumper;
59: my (@data, @lol);
60:
61: # Example: iterate over a multi-value list
62: @data = qw(1 one uno 2 two dos 3 three tres 4 four quatro 5 five cinco);
63: iterstart @data;
64: while (my ($num, $eng, $span) = iter 3) {
65: print "$num is $eng in English and $span in Spanish\n";
66: }
67:
68: # Example: convert a flat data structure to a list-of-lists
69: @data = qw(1 fee 2 fee fi 3 fee fi fo 4 fee fi fo fum 1 fin);
70: iterstart @data;
71: while (my ($len) = iter) {
72: push @lol, [iter $len];
73: }
74: print Dumper \@lol;
|
|---|
| Replies are listed 'Best First'. | |
|---|---|
|
Re: iter
by Dominus (Parson) on Mar 27, 2001 at 22:12 UTC | |
by MeowChow (Vicar) on Mar 27, 2001 at 22:25 UTC | |
by MeowChow (Vicar) on Mar 28, 2001 at 07:50 UTC |