line |
stmt |
bran |
cond |
sub |
pod |
time |
code |
1
|
|
|
|
|
|
|
package Iterator::Simple::Util; |
2
|
|
|
|
|
|
|
{ |
3
|
|
|
|
|
|
|
$Iterator::Simple::Util::VERSION = '0.002'; |
4
|
|
|
|
|
|
|
} |
5
|
|
|
|
|
|
|
|
6
|
|
|
|
|
|
|
# ABSTRACT: Port of List::Util and List::MoreUtils to Iterator::Simple |
7
|
|
|
|
|
|
|
|
8
|
1
|
|
|
1
|
|
94025
|
use strict; |
|
1
|
|
|
|
|
3
|
|
|
1
|
|
|
|
|
33
|
|
9
|
1
|
|
|
1
|
|
5
|
use warnings FATAL => 'all'; |
|
1
|
|
|
|
|
1
|
|
|
1
|
|
|
|
|
66
|
|
10
|
|
|
|
|
|
|
|
11
|
1
|
|
|
|
|
13
|
use Sub::Exporter -setup => { |
12
|
|
|
|
|
|
|
exports => [ qw( igroup ireduce isum |
13
|
|
|
|
|
|
|
imax imin imaxstr iminstr imax_by imin_by imaxstr_by iminstr_by |
14
|
|
|
|
|
|
|
iany inone inotall |
15
|
|
|
|
|
|
|
ifirstval ilastval |
16
|
|
|
|
|
|
|
ibefore ibefore_incl iafter iafter_incl |
17
|
|
|
|
|
|
|
inatatime |
18
|
|
|
|
|
|
|
) |
19
|
|
|
|
|
|
|
] |
20
|
1
|
|
|
1
|
|
1033
|
}; |
|
1
|
|
|
|
|
12345
|
|
21
|
|
|
|
|
|
|
|
22
|
1
|
|
|
1
|
|
604
|
use Const::Fast; |
|
1
|
|
|
|
|
2
|
|
|
1
|
|
|
|
|
8
|
|
23
|
1
|
|
|
1
|
|
75
|
use Iterator::Simple qw( iter iterator ichain ); |
|
1
|
|
|
|
|
3
|
|
|
1
|
|
|
|
|
280
|
|
24
|
|
|
|
|
|
|
|
25
|
|
|
|
|
|
|
const my $TRUE => !0; |
26
|
|
|
|
|
|
|
const my $FALSE => !1; |
27
|
|
|
|
|
|
|
|
28
|
|
|
|
|
|
|
sub _ensure_coderef { |
29
|
35
|
50
|
|
35
|
|
109
|
unless( ref( shift ) eq 'CODE' ) { |
30
|
0
|
|
|
|
|
0
|
require Carp; |
31
|
0
|
|
|
|
|
0
|
Carp::croak("Not a subroutine reference"); |
32
|
|
|
|
|
|
|
} |
33
|
|
|
|
|
|
|
} |
34
|
|
|
|
|
|
|
|
35
|
|
|
|
|
|
|
sub _wrap_code { |
36
|
5
|
|
|
5
|
|
8
|
my $code = shift; |
37
|
|
|
|
|
|
|
|
38
|
|
|
|
|
|
|
return sub { |
39
|
60
|
|
|
60
|
|
150
|
$_ = shift; |
40
|
60
|
|
|
|
|
121
|
$code->(); |
41
|
5
|
|
|
|
|
18
|
}; |
42
|
|
|
|
|
|
|
} |
43
|
|
|
|
|
|
|
|
44
|
|
|
|
|
|
|
|
45
|
|
|
|
|
|
|
sub igroup (&$) { |
46
|
2
|
|
|
2
|
1
|
7298
|
my ( $is_same_group, $base_iter ) = @_; |
47
|
|
|
|
|
|
|
|
48
|
2
|
|
|
|
|
10
|
_ensure_coderef( $is_same_group ); |
49
|
|
|
|
|
|
|
|
50
|
2
|
|
|
|
|
11
|
$base_iter = iter $base_iter; |
51
|
|
|
|
|
|
|
|
52
|
2
|
|
|
|
|
64
|
my $next_record = $base_iter->next; |
53
|
|
|
|
|
|
|
|
54
|
|
|
|
|
|
|
# Localize caller's $a and $b |
55
|
2
|
|
|
|
|
13
|
my ( $caller_a, $caller_b ) = do { |
56
|
2
|
|
|
|
|
16
|
require B; |
57
|
2
|
|
|
|
|
36
|
my $caller = B::svref_2object( $is_same_group )->STASH->NAME; |
58
|
1
|
|
|
1
|
|
6
|
no strict 'refs'; |
|
1
|
|
|
|
|
2
|
|
|
1
|
|
|
|
|
296
|
|
59
|
2
|
|
|
|
|
41
|
map \*{$caller.'::'.$_}, qw( a b ); |
|
4
|
|
|
|
|
16
|
|
60
|
|
|
|
|
|
|
}; |
61
|
2
|
|
|
|
|
7
|
local ( *$caller_a, *$caller_b ); |
62
|
|
|
|
|
|
|
|
63
|
|
|
|
|
|
|
return iterator { |
64
|
6
|
100
|
|
6
|
|
3212
|
defined( my $base_record = $next_record ) |
65
|
|
|
|
|
|
|
or return; |
66
|
|
|
|
|
|
|
|
67
|
|
|
|
|
|
|
return iterator { |
68
|
13
|
100
|
|
|
|
2314
|
return unless defined $next_record; |
69
|
12
|
|
|
|
|
27
|
( *$caller_a, *$caller_b ) = \( $base_record, $next_record ); |
70
|
12
|
100
|
|
|
|
31
|
return unless $is_same_group->(); |
71
|
9
|
|
|
|
|
222
|
my $res = $next_record; |
72
|
9
|
|
|
|
|
28
|
$next_record = $base_iter->next; |
73
|
9
|
|
|
|
|
59
|
return $res; |
74
|
4
|
|
|
|
|
23
|
}; |
75
|
2
|
|
|
|
|
22
|
}; |
76
|
|
|
|
|
|
|
} |
77
|
|
|
|
|
|
|
|
78
|
|
|
|
|
|
|
|
79
|
|
|
|
|
|
|
sub ireduce (&$;$) { |
80
|
|
|
|
|
|
|
|
81
|
16
|
|
|
16
|
1
|
1465
|
my ( $code, $init_val, $iter ); |
82
|
|
|
|
|
|
|
|
83
|
16
|
100
|
|
|
|
35
|
if ( @_ == 2 ) { |
84
|
13
|
|
|
|
|
25
|
( $code, $iter ) = @_; |
85
|
|
|
|
|
|
|
} |
86
|
|
|
|
|
|
|
else { |
87
|
3
|
|
|
|
|
6
|
( $code, $init_val, $iter ) = @_; |
88
|
|
|
|
|
|
|
} |
89
|
|
|
|
|
|
|
|
90
|
16
|
|
|
|
|
30
|
_ensure_coderef( $code ); |
91
|
16
|
|
|
|
|
39
|
$iter = iter $iter; |
92
|
|
|
|
|
|
|
|
93
|
|
|
|
|
|
|
# Localize caller's $a and $b |
94
|
16
|
|
|
|
|
158
|
my ( $caller_a, $caller_b ) = do { |
95
|
16
|
|
|
|
|
80
|
require B; |
96
|
16
|
|
|
|
|
106
|
my $caller = B::svref_2object( $code )->STASH->NAME; |
97
|
1
|
|
|
1
|
|
5
|
no strict 'refs'; |
|
1
|
|
|
|
|
3
|
|
|
1
|
|
|
|
|
1836
|
|
98
|
16
|
|
|
|
|
33
|
map \*{$caller.'::'.$_}, qw( a b ); |
|
32
|
|
|
|
|
112
|
|
99
|
|
|
|
|
|
|
}; |
100
|
16
|
|
|
|
|
39
|
local ( *$caller_a, *$caller_b ) = \my ( $x, $y ); |
101
|
|
|
|
|
|
|
|
102
|
16
|
100
|
|
|
|
61
|
$x = @_ == 3 ? $init_val : $iter->next; |
103
|
|
|
|
|
|
|
|
104
|
16
|
100
|
|
|
|
113
|
defined( $x ) |
105
|
|
|
|
|
|
|
or return; |
106
|
|
|
|
|
|
|
|
107
|
15
|
100
|
|
|
|
39
|
defined( $y = $iter->next ) |
108
|
|
|
|
|
|
|
or return $x; |
109
|
|
|
|
|
|
|
|
110
|
14
|
|
66
|
|
|
136
|
while( defined $x and defined $y ) { |
111
|
100
|
|
|
|
|
705
|
$x = $code->(); |
112
|
100
|
|
|
|
|
387
|
$y = $iter->next; |
113
|
|
|
|
|
|
|
} |
114
|
|
|
|
|
|
|
|
115
|
14
|
|
|
|
|
159
|
return $x; |
116
|
|
|
|
|
|
|
} |
117
|
|
|
|
|
|
|
|
118
|
|
|
|
|
|
|
|
119
|
|
|
|
|
|
|
sub isum ($;$) { |
120
|
2
|
|
|
2
|
1
|
460
|
my ( $init_val, $iter ); |
121
|
|
|
|
|
|
|
|
122
|
2
|
100
|
|
|
|
7
|
if ( @_ == 1 ) { |
123
|
1
|
|
|
|
|
1
|
$init_val = 0; |
124
|
1
|
|
|
|
|
3
|
$iter = $_[0]; |
125
|
|
|
|
|
|
|
} |
126
|
|
|
|
|
|
|
else { |
127
|
1
|
|
|
|
|
4
|
( $init_val, $iter ) = @_; |
128
|
|
|
|
|
|
|
} |
129
|
|
|
|
|
|
|
|
130
|
2
|
|
|
20
|
|
9
|
ireduce { $a + $b } $init_val, $iter; |
|
20
|
|
|
|
|
29
|
|
131
|
|
|
|
|
|
|
} |
132
|
|
|
|
|
|
|
|
133
|
|
|
|
|
|
|
|
134
|
|
|
|
|
|
|
sub imax ($) { |
135
|
8
|
100
|
|
8
|
1
|
20
|
ireduce { $a > $b ? $a : $b } shift; |
|
1
|
|
|
1
|
|
23
|
|
136
|
|
|
|
|
|
|
} |
137
|
|
|
|
|
|
|
|
138
|
|
|
|
|
|
|
|
139
|
|
|
|
|
|
|
sub imin ($) { |
140
|
8
|
100
|
|
8
|
1
|
19
|
ireduce { $a < $b ? $a : $b } shift; |
|
1
|
|
|
1
|
|
21
|
|
141
|
|
|
|
|
|
|
} |
142
|
|
|
|
|
|
|
|
143
|
|
|
|
|
|
|
|
144
|
|
|
|
|
|
|
sub imax_by (&$) { |
145
|
1
|
|
|
1
|
1
|
878
|
my ( $code, $iter ) = @_; |
146
|
|
|
|
|
|
|
|
147
|
1
|
|
|
|
|
4
|
_ensure_coderef( $code ); |
148
|
1
|
|
|
|
|
4
|
$code = _wrap_code( $code ); |
149
|
|
|
|
|
|
|
|
150
|
1
|
100
|
|
8
|
|
5
|
ireduce { $code->($a) > $code->($b) ? $a : $b } $iter; |
|
8
|
|
|
|
|
13
|
|
151
|
|
|
|
|
|
|
} |
152
|
|
|
|
|
|
|
|
153
|
|
|
|
|
|
|
|
154
|
|
|
|
|
|
|
sub imin_by (&$) { |
155
|
2
|
|
|
2
|
1
|
37
|
my ( $code, $iter ) = @_; |
156
|
|
|
|
|
|
|
|
157
|
2
|
|
|
|
|
5
|
_ensure_coderef( $code ); |
158
|
2
|
|
|
|
|
5
|
$code = _wrap_code( $code ); |
159
|
|
|
|
|
|
|
|
160
|
2
|
100
|
|
16
|
|
9
|
ireduce { $code->($a) < $code->($b) ? $a : $b } $iter; |
|
16
|
|
|
|
|
26
|
|
161
|
|
|
|
|
|
|
} |
162
|
|
|
|
|
|
|
|
163
|
|
|
|
|
|
|
|
164
|
|
|
|
|
|
|
sub imaxstr ($) { |
165
|
3
|
100
|
|
3
|
1
|
11
|
ireduce { $a gt $b ? $a : $b } shift; |
|
1
|
|
|
1
|
|
616
|
|
166
|
|
|
|
|
|
|
} |
167
|
|
|
|
|
|
|
|
168
|
|
|
|
|
|
|
|
169
|
|
|
|
|
|
|
sub iminstr ($) { |
170
|
3
|
100
|
|
3
|
1
|
10
|
ireduce { $a lt $b ? $a : $b } shift; |
|
1
|
|
|
1
|
|
6
|
|
171
|
|
|
|
|
|
|
} |
172
|
|
|
|
|
|
|
|
173
|
|
|
|
|
|
|
|
174
|
|
|
|
|
|
|
sub imaxstr_by (&$) { |
175
|
1
|
|
|
1
|
1
|
474
|
my ( $code, $iter ) = @_; |
176
|
|
|
|
|
|
|
|
177
|
1
|
|
|
|
|
5
|
_ensure_coderef( $code ); |
178
|
1
|
|
|
|
|
3
|
$code = _wrap_code( $code ); |
179
|
|
|
|
|
|
|
|
180
|
1
|
100
|
|
3
|
|
6
|
ireduce { $code->($a) gt $code->($b) ? $a : $b } $iter; |
|
3
|
|
|
|
|
7
|
|
181
|
|
|
|
|
|
|
} |
182
|
|
|
|
|
|
|
|
183
|
|
|
|
|
|
|
|
184
|
|
|
|
|
|
|
sub iminstr_by (&$) { |
185
|
1
|
|
|
1
|
1
|
24
|
my ( $code, $iter ) = @_; |
186
|
|
|
|
|
|
|
|
187
|
1
|
|
|
|
|
3
|
_ensure_coderef( $code ); |
188
|
1
|
|
|
|
|
7
|
$code = _wrap_code( $code ); |
189
|
|
|
|
|
|
|
|
190
|
1
|
50
|
|
3
|
|
6
|
ireduce { $code->($a) lt $code->($b) ? $a : $b } $iter; |
|
3
|
|
|
|
|
7
|
|
191
|
|
|
|
|
|
|
} |
192
|
|
|
|
|
|
|
|
193
|
|
|
|
|
|
|
|
194
|
|
|
|
|
|
|
sub iany (&$) { |
195
|
2
|
|
|
2
|
1
|
480
|
my ( $code, $iter ) = @_; |
196
|
|
|
|
|
|
|
|
197
|
2
|
|
|
|
|
6
|
_ensure_coderef( $code ); |
198
|
2
|
|
|
|
|
5
|
$iter = iter $iter; |
199
|
|
|
|
|
|
|
|
200
|
2
|
|
|
|
|
24
|
while( defined( $_ = $iter->next ) ) { |
201
|
15
|
100
|
|
|
|
151
|
$code->() and return $TRUE; |
202
|
|
|
|
|
|
|
} |
203
|
|
|
|
|
|
|
|
204
|
1
|
|
|
|
|
12
|
return $FALSE; |
205
|
|
|
|
|
|
|
} |
206
|
|
|
|
|
|
|
|
207
|
|
|
|
|
|
|
|
208
|
|
|
|
|
|
|
sub inone (&$) { |
209
|
2
|
|
|
2
|
1
|
37
|
my ( $code, $iter ) = @_; |
210
|
|
|
|
|
|
|
|
211
|
2
|
|
|
|
|
6
|
_ensure_coderef( $code ); |
212
|
2
|
|
|
|
|
5
|
$iter = iter $iter; |
213
|
|
|
|
|
|
|
|
214
|
2
|
|
|
|
|
21
|
while( defined( $_ = $iter->next ) ) { |
215
|
15
|
100
|
|
|
|
177
|
$code->() and return $FALSE; |
216
|
|
|
|
|
|
|
} |
217
|
|
|
|
|
|
|
|
218
|
1
|
|
|
|
|
13
|
return $TRUE; |
219
|
|
|
|
|
|
|
} |
220
|
|
|
|
|
|
|
|
221
|
|
|
|
|
|
|
|
222
|
|
|
|
|
|
|
sub inotall (&$) { |
223
|
2
|
|
|
2
|
1
|
35
|
my ( $code, $iter ) = @_; |
224
|
|
|
|
|
|
|
|
225
|
2
|
|
|
|
|
6
|
_ensure_coderef( $code ); |
226
|
2
|
|
|
|
|
5
|
$iter = iter $iter; |
227
|
|
|
|
|
|
|
|
228
|
2
|
|
|
|
|
21
|
while( defined( $_ = $iter->next ) ) { |
229
|
12
|
100
|
|
|
|
129
|
return $TRUE if ! $code->(); |
230
|
|
|
|
|
|
|
} |
231
|
|
|
|
|
|
|
|
232
|
1
|
|
|
|
|
13
|
return $FALSE; |
233
|
|
|
|
|
|
|
} |
234
|
|
|
|
|
|
|
|
235
|
|
|
|
|
|
|
|
236
|
|
|
|
|
|
|
sub ifirstval (&$) { |
237
|
1
|
|
|
1
|
1
|
20
|
my ( $code, $iter ) = @_; |
238
|
1
|
|
|
|
|
3
|
_ensure_coderef( $code ); |
239
|
1
|
|
|
|
|
3
|
$iter = iter $iter; |
240
|
|
|
|
|
|
|
|
241
|
1
|
|
|
|
|
12
|
while( defined( $_ = $iter->next ) ) { |
242
|
4
|
100
|
|
|
|
40
|
$code->() and return $_; |
243
|
|
|
|
|
|
|
} |
244
|
|
|
|
|
|
|
|
245
|
0
|
|
|
|
|
0
|
return; |
246
|
|
|
|
|
|
|
} |
247
|
|
|
|
|
|
|
|
248
|
|
|
|
|
|
|
|
249
|
|
|
|
|
|
|
sub ilastval (&$) { |
250
|
1
|
|
|
1
|
1
|
428
|
my ( $code, $iter ) = @_; |
251
|
|
|
|
|
|
|
|
252
|
1
|
|
|
|
|
3
|
_ensure_coderef( $code ); |
253
|
1
|
|
|
|
|
6
|
$iter = iter $iter; |
254
|
|
|
|
|
|
|
|
255
|
1
|
|
|
|
|
9
|
my $val; |
256
|
1
|
|
|
|
|
11
|
while( defined( $_ = $iter->next ) ) { |
257
|
11
|
100
|
|
|
|
109
|
$val = $_ if $code->(); |
258
|
|
|
|
|
|
|
} |
259
|
|
|
|
|
|
|
|
260
|
1
|
|
|
|
|
10
|
return $val; |
261
|
|
|
|
|
|
|
} |
262
|
|
|
|
|
|
|
|
263
|
|
|
|
|
|
|
|
264
|
|
|
|
|
|
|
sub ibefore (&$) { |
265
|
1
|
|
|
1
|
1
|
431
|
my ( $code, $iter ) = @_; |
266
|
|
|
|
|
|
|
|
267
|
1
|
|
|
|
|
4
|
_ensure_coderef( $code ); |
268
|
1
|
|
|
|
|
3
|
$iter = iter $iter; |
269
|
|
|
|
|
|
|
|
270
|
|
|
|
|
|
|
return iterator { |
271
|
4
|
50
|
|
4
|
|
615
|
defined( $_ = $iter->next ) |
272
|
|
|
|
|
|
|
or return; |
273
|
4
|
100
|
|
|
|
34
|
$code->() |
274
|
|
|
|
|
|
|
and return; |
275
|
3
|
|
|
|
|
17
|
return $_; |
276
|
1
|
|
|
|
|
15
|
}; |
277
|
|
|
|
|
|
|
} |
278
|
|
|
|
|
|
|
|
279
|
|
|
|
|
|
|
|
280
|
|
|
|
|
|
|
sub ibefore_incl (&$) { |
281
|
1
|
|
|
1
|
1
|
695
|
my ( $code, $iter ) = @_; |
282
|
|
|
|
|
|
|
|
283
|
1
|
|
|
|
|
4
|
_ensure_coderef( $code ); |
284
|
1
|
|
|
|
|
4
|
$iter = iter $iter; |
285
|
|
|
|
|
|
|
|
286
|
1
|
|
|
|
|
40
|
my $done = $FALSE; |
287
|
|
|
|
|
|
|
|
288
|
|
|
|
|
|
|
return iterator { |
289
|
5
|
100
|
66
|
5
|
|
601
|
not( $done ) and defined( $_ = $iter->next ) |
290
|
|
|
|
|
|
|
or return; |
291
|
4
|
100
|
|
|
|
37
|
$code->() and $done = $TRUE; |
292
|
4
|
|
|
|
|
22
|
return $_; |
293
|
1
|
|
|
|
|
7
|
}; |
294
|
|
|
|
|
|
|
} |
295
|
|
|
|
|
|
|
|
296
|
|
|
|
|
|
|
|
297
|
|
|
|
|
|
|
sub iafter (&$) { |
298
|
1
|
|
|
1
|
1
|
809
|
my ( $code, $iter ) = @_; |
299
|
|
|
|
|
|
|
|
300
|
1
|
|
|
|
|
3
|
_ensure_coderef( $code ); |
301
|
1
|
|
|
|
|
3
|
$iter = iter $iter; |
302
|
|
|
|
|
|
|
|
303
|
1
|
|
|
|
|
11
|
while( defined( $_ = $iter->next ) ) { |
304
|
4
|
100
|
|
|
|
39
|
last if $code->(); |
305
|
|
|
|
|
|
|
} |
306
|
|
|
|
|
|
|
|
307
|
1
|
|
|
|
|
8
|
return $iter; |
308
|
|
|
|
|
|
|
} |
309
|
|
|
|
|
|
|
|
310
|
|
|
|
|
|
|
|
311
|
|
|
|
|
|
|
sub iafter_incl (&$) { |
312
|
1
|
|
|
1
|
1
|
632
|
my ( $code, $iter ) = @_; |
313
|
|
|
|
|
|
|
|
314
|
1
|
|
|
|
|
5
|
_ensure_coderef( $code ); |
315
|
1
|
|
|
|
|
4
|
$iter = iter $iter; |
316
|
|
|
|
|
|
|
|
317
|
1
|
|
|
|
|
58
|
while( defined( $_ = $iter->next ) ) { |
318
|
4
|
100
|
|
|
|
43
|
last if $code->(); |
319
|
|
|
|
|
|
|
} |
320
|
|
|
|
|
|
|
|
321
|
1
|
|
|
|
|
8
|
return ichain iter( [$_] ), $iter; |
322
|
|
|
|
|
|
|
} |
323
|
|
|
|
|
|
|
|
324
|
|
|
|
|
|
|
|
325
|
|
|
|
|
|
|
sub inatatime ($$) { |
326
|
1
|
|
|
1
|
1
|
1348
|
my ($kicks, $iter) = @_; |
327
|
|
|
|
|
|
|
|
328
|
1
|
|
|
|
|
4
|
$iter = iter $iter; |
329
|
|
|
|
|
|
|
|
330
|
|
|
|
|
|
|
return iterator { |
331
|
5
|
|
|
5
|
|
622
|
my @vals; |
332
|
|
|
|
|
|
|
|
333
|
5
|
|
|
|
|
10
|
for (1 .. $kicks) { |
334
|
13
|
|
|
|
|
34
|
my $val = $iter->next; |
335
|
13
|
100
|
|
|
|
79
|
last unless defined $val; |
336
|
11
|
|
|
|
|
24
|
push @vals, $val; |
337
|
|
|
|
|
|
|
} |
338
|
5
|
100
|
|
|
|
18
|
return @vals ? \@vals : undef; |
339
|
1
|
|
|
|
|
15
|
}; |
340
|
|
|
|
|
|
|
} |
341
|
|
|
|
|
|
|
|
342
|
|
|
|
|
|
|
|
343
|
|
|
|
|
|
|
1; |
344
|
|
|
|
|
|
|
|
345
|
|
|
|
|
|
|
|
346
|
|
|
|
|
|
|
|
347
|
|
|
|
|
|
|
=pod |
348
|
|
|
|
|
|
|
|
349
|
|
|
|
|
|
|
=head1 NAME |
350
|
|
|
|
|
|
|
|
351
|
|
|
|
|
|
|
Iterator::Simple::Util - Port of List::Util and List::MoreUtils to Iterator::Simple |
352
|
|
|
|
|
|
|
|
353
|
|
|
|
|
|
|
=head1 VERSION |
354
|
|
|
|
|
|
|
|
355
|
|
|
|
|
|
|
version 0.002 |
356
|
|
|
|
|
|
|
|
357
|
|
|
|
|
|
|
=head1 SYNOPSIS |
358
|
|
|
|
|
|
|
|
359
|
|
|
|
|
|
|
use Iterator::Simple::Util qw( igroup ireduce isum |
360
|
|
|
|
|
|
|
imax imin imaxstr iminstr imax_by imin_by imaxstr_by iminstr_by |
361
|
|
|
|
|
|
|
iany inone inotall |
362
|
|
|
|
|
|
|
ifirstval ilastval |
363
|
|
|
|
|
|
|
ibefore ibefore_incl iafter iafter_incl |
364
|
|
|
|
|
|
|
inatatime ); |
365
|
|
|
|
|
|
|
|
366
|
|
|
|
|
|
|
=head1 DESCRIPTION |
367
|
|
|
|
|
|
|
|
368
|
|
|
|
|
|
|
B implements many of the functions from |
369
|
|
|
|
|
|
|
L and L for iterators generated by |
370
|
|
|
|
|
|
|
L. |
371
|
|
|
|
|
|
|
|
372
|
|
|
|
|
|
|
=head1 EXPORTS |
373
|
|
|
|
|
|
|
|
374
|
|
|
|
|
|
|
All of these functions call C on the |
375
|
|
|
|
|
|
|
I> argument; this detects what I> is and turns it |
376
|
|
|
|
|
|
|
into an iterator. See L for details. |
377
|
|
|
|
|
|
|
|
378
|
|
|
|
|
|
|
Functions taking a I expect a code block that operates on |
379
|
|
|
|
|
|
|
C<$_> or, in the case of B and B, on C<$a> and C<$b>. |
380
|
|
|
|
|
|
|
|
381
|
|
|
|
|
|
|
=over 4 |
382
|
|
|
|
|
|
|
|
383
|
|
|
|
|
|
|
=item igroup I I |
384
|
|
|
|
|
|
|
|
385
|
|
|
|
|
|
|
=item ireduce I [I] I |
386
|
|
|
|
|
|
|
|
387
|
|
|
|
|
|
|
Reduces I by calling I, in a scalar context, multiple times, |
388
|
|
|
|
|
|
|
setting C<$a> and C<$b> each time. The first call will be with C<$a> |
389
|
|
|
|
|
|
|
and C<$b> set to the first two elements of the list, subsequent |
390
|
|
|
|
|
|
|
calls will be done by setting C<$a> to the result of the previous |
391
|
|
|
|
|
|
|
call and C<$b> to the next element in the list. |
392
|
|
|
|
|
|
|
|
393
|
|
|
|
|
|
|
Returns the result of the last call to I. If the iterator is |
394
|
|
|
|
|
|
|
empty then C is returned. If the iterator only contains one |
395
|
|
|
|
|
|
|
element then that element is returned and I is not executed. |
396
|
|
|
|
|
|
|
|
397
|
|
|
|
|
|
|
$foo = ireduce { $a < $b ? $a : $b } $iterator # min |
398
|
|
|
|
|
|
|
$foo = ireduce { $a lt $b ? $a : $b } $iterator # minstr |
399
|
|
|
|
|
|
|
$foo = ireduce { $a + $b } $iterator # sum |
400
|
|
|
|
|
|
|
$foo = ireduce { $a . $b } $iterator # concat |
401
|
|
|
|
|
|
|
|
402
|
|
|
|
|
|
|
If your algorithm requires that C produce an identity value, then |
403
|
|
|
|
|
|
|
make sure that you always pass that identity value as the first argument to prevent |
404
|
|
|
|
|
|
|
C being returned. For example: |
405
|
|
|
|
|
|
|
|
406
|
|
|
|
|
|
|
$foo = ireduce { $a + $b } 0, $iterator |
407
|
|
|
|
|
|
|
|
408
|
|
|
|
|
|
|
will return 0 (rather than C) when C<$iterator> is empty. |
409
|
|
|
|
|
|
|
|
410
|
|
|
|
|
|
|
=item isum [I] I |
411
|
|
|
|
|
|
|
|
412
|
|
|
|
|
|
|
Returns the sum of the elements of I, which should return |
413
|
|
|
|
|
|
|
numeric values. Returns 0 if the iterator is empty. |
414
|
|
|
|
|
|
|
|
415
|
|
|
|
|
|
|
=item imax I |
416
|
|
|
|
|
|
|
|
417
|
|
|
|
|
|
|
Returns the maximum value of I, which should produce numeric |
418
|
|
|
|
|
|
|
values. Retruns C if the iterator is empty. |
419
|
|
|
|
|
|
|
|
420
|
|
|
|
|
|
|
=item imin I |
421
|
|
|
|
|
|
|
|
422
|
|
|
|
|
|
|
Returns the minimum value of I, which should produce numeric |
423
|
|
|
|
|
|
|
values. Returns C if the iterator is empty. |
424
|
|
|
|
|
|
|
|
425
|
|
|
|
|
|
|
=item imax_by I I |
426
|
|
|
|
|
|
|
|
427
|
|
|
|
|
|
|
Return the value of I for which I produces the maximum value. |
428
|
|
|
|
|
|
|
For example: |
429
|
|
|
|
|
|
|
|
430
|
|
|
|
|
|
|
imax_by { $_ * $_ } iter( [ -5 -2 -1 0 1 2 ] ) |
431
|
|
|
|
|
|
|
|
432
|
|
|
|
|
|
|
will return C<-5>. |
433
|
|
|
|
|
|
|
|
434
|
|
|
|
|
|
|
=item imin_by I I |
435
|
|
|
|
|
|
|
|
436
|
|
|
|
|
|
|
Similar to B, but returns the value of I for which |
437
|
|
|
|
|
|
|
I produces the minimum value. |
438
|
|
|
|
|
|
|
|
439
|
|
|
|
|
|
|
=item imaxstr I |
440
|
|
|
|
|
|
|
|
441
|
|
|
|
|
|
|
Similar to B, but expects I to return string values. |
442
|
|
|
|
|
|
|
|
443
|
|
|
|
|
|
|
=item iminstr I |
444
|
|
|
|
|
|
|
|
445
|
|
|
|
|
|
|
Similar to B, but expects I to return string values. |
446
|
|
|
|
|
|
|
|
447
|
|
|
|
|
|
|
=item imaxstr_by I I |
448
|
|
|
|
|
|
|
|
449
|
|
|
|
|
|
|
Similar to B, but expects I to return string values. |
450
|
|
|
|
|
|
|
|
451
|
|
|
|
|
|
|
=item iminstr_by I I |
452
|
|
|
|
|
|
|
|
453
|
|
|
|
|
|
|
Similar to B, but expects I to return string values. |
454
|
|
|
|
|
|
|
|
455
|
|
|
|
|
|
|
=item iany I I |
456
|
|
|
|
|
|
|
|
457
|
|
|
|
|
|
|
Returns a true value if any item produced by I meets the |
458
|
|
|
|
|
|
|
criterion given through I. Sets C<$_> for each item in turn: |
459
|
|
|
|
|
|
|
|
460
|
|
|
|
|
|
|
print "At least one value greater than 10" |
461
|
|
|
|
|
|
|
if iany { $_ > 10 } $iterator; |
462
|
|
|
|
|
|
|
|
463
|
|
|
|
|
|
|
Returns false otherwise, or if the iterator is empty. |
464
|
|
|
|
|
|
|
|
465
|
|
|
|
|
|
|
=item inone I I |
466
|
|
|
|
|
|
|
|
467
|
|
|
|
|
|
|
Returns a true value if no item produced by I meets the |
468
|
|
|
|
|
|
|
criterion given through I, or if the iterator is empty. Sets |
469
|
|
|
|
|
|
|
C<$_> for each item in turn: |
470
|
|
|
|
|
|
|
|
471
|
|
|
|
|
|
|
print "No values greater than 10" |
472
|
|
|
|
|
|
|
if inone { $_ > 10 } $iterator; |
473
|
|
|
|
|
|
|
|
474
|
|
|
|
|
|
|
Returns false otherwise. |
475
|
|
|
|
|
|
|
|
476
|
|
|
|
|
|
|
=item inotall I I |
477
|
|
|
|
|
|
|
|
478
|
|
|
|
|
|
|
Logically the negation of I. Returns true if I returns |
479
|
|
|
|
|
|
|
false for some value of I: |
480
|
|
|
|
|
|
|
|
481
|
|
|
|
|
|
|
print "Not all even" |
482
|
|
|
|
|
|
|
if inotall { $_ % 2 == 0 } $iterator; |
483
|
|
|
|
|
|
|
|
484
|
|
|
|
|
|
|
Returns false if the iterator is empty, or all values of I |
485
|
|
|
|
|
|
|
produces a true value for every item produced by I. |
486
|
|
|
|
|
|
|
|
487
|
|
|
|
|
|
|
=item ifirstval I I |
488
|
|
|
|
|
|
|
|
489
|
|
|
|
|
|
|
Returns the first element produced by I for which I |
490
|
|
|
|
|
|
|
evaluates to true. Each element produced by I is set to |
491
|
|
|
|
|
|
|
C<$_> in turn. Returns C if no such element has been found. |
492
|
|
|
|
|
|
|
|
493
|
|
|
|
|
|
|
=item ilastval I I |
494
|
|
|
|
|
|
|
|
495
|
|
|
|
|
|
|
Returns the last element produced by I for which I |
496
|
|
|
|
|
|
|
evaluates to true. Each element of I is set to C<$_> in |
497
|
|
|
|
|
|
|
turn. Returns C if no such element has been found. |
498
|
|
|
|
|
|
|
|
499
|
|
|
|
|
|
|
=item ibefore I I |
500
|
|
|
|
|
|
|
|
501
|
|
|
|
|
|
|
Returns an iterator that will produce all values of I upto |
502
|
|
|
|
|
|
|
(and not including) the point where I returns a true |
503
|
|
|
|
|
|
|
value. Sets C<$_> for each element in turn. |
504
|
|
|
|
|
|
|
|
505
|
|
|
|
|
|
|
=item ibefore_incl I I |
506
|
|
|
|
|
|
|
|
507
|
|
|
|
|
|
|
Returns an iterator that will produce all values of I upto |
508
|
|
|
|
|
|
|
(and including) the point where I returns a true value. Sets |
509
|
|
|
|
|
|
|
C<$_> for each element in turn. |
510
|
|
|
|
|
|
|
|
511
|
|
|
|
|
|
|
=item iafter I I |
512
|
|
|
|
|
|
|
|
513
|
|
|
|
|
|
|
Returns an iterator that will produce all values of I after |
514
|
|
|
|
|
|
|
(and not including) the point where I returns a true |
515
|
|
|
|
|
|
|
value. Sets C<$_> for each element in turn. |
516
|
|
|
|
|
|
|
|
517
|
|
|
|
|
|
|
$it = iafter { $_ % 5 == 0 } [1..9]; # $it returns 6, 7, 8, 9 |
518
|
|
|
|
|
|
|
|
519
|
|
|
|
|
|
|
=item iafter_incl I I |
520
|
|
|
|
|
|
|
|
521
|
|
|
|
|
|
|
Returns an iterator that will produce all values of I after |
522
|
|
|
|
|
|
|
(and including) the point where I returns a true value. Sets |
523
|
|
|
|
|
|
|
C<$_> for each element in turn. |
524
|
|
|
|
|
|
|
|
525
|
|
|
|
|
|
|
$it = iafter_incl { $_ % 5 == 0 } [1..9]; # $it returns 5, 6, 7, 8, 9 |
526
|
|
|
|
|
|
|
|
527
|
|
|
|
|
|
|
=item inatatime I I |
528
|
|
|
|
|
|
|
|
529
|
|
|
|
|
|
|
Creates an array iterator that returns array refs of elements from |
530
|
|
|
|
|
|
|
I, I items at a time. For example: |
531
|
|
|
|
|
|
|
|
532
|
|
|
|
|
|
|
my $it = inatatime 3, iter( [ 'a' .. 'g' ] ); |
533
|
|
|
|
|
|
|
while( my $vals = $it->next ) { |
534
|
|
|
|
|
|
|
print join( ' ', @{$vals} ) . "\n"; |
535
|
|
|
|
|
|
|
} |
536
|
|
|
|
|
|
|
|
537
|
|
|
|
|
|
|
This prints: |
538
|
|
|
|
|
|
|
|
539
|
|
|
|
|
|
|
a b c |
540
|
|
|
|
|
|
|
d e f |
541
|
|
|
|
|
|
|
g |
542
|
|
|
|
|
|
|
|
543
|
|
|
|
|
|
|
=back |
544
|
|
|
|
|
|
|
|
545
|
|
|
|
|
|
|
=head1 AUTHOR |
546
|
|
|
|
|
|
|
|
547
|
|
|
|
|
|
|
Ray Miller |
548
|
|
|
|
|
|
|
|
549
|
|
|
|
|
|
|
=head1 COPYRIGHT AND LICENSE |
550
|
|
|
|
|
|
|
|
551
|
|
|
|
|
|
|
This software is copyright (c) 2012 by Ray Miller. |
552
|
|
|
|
|
|
|
|
553
|
|
|
|
|
|
|
This is free software; you can redistribute it and/or modify it under |
554
|
|
|
|
|
|
|
the same terms as the Perl 5 programming language system itself. |
555
|
|
|
|
|
|
|
|
556
|
|
|
|
|
|
|
=cut |
557
|
|
|
|
|
|
|
|
558
|
|
|
|
|
|
|
|
559
|
|
|
|
|
|
|
__END__ |