line |
stmt |
bran |
cond |
sub |
pod |
time |
code |
1
|
|
|
|
|
|
|
package List::Objects::WithUtils::Role::Array; |
2
|
|
|
|
|
|
|
$List::Objects::WithUtils::Role::Array::VERSION = '2.028003'; |
3
|
208
|
|
|
208
|
|
107687
|
use strictures 2; |
|
208
|
|
|
|
|
1051
|
|
|
208
|
|
|
|
|
7360
|
|
4
|
|
|
|
|
|
|
|
5
|
208
|
|
|
208
|
|
27731
|
use Carp (); |
|
208
|
|
|
|
|
242
|
|
|
208
|
|
|
|
|
2301
|
|
6
|
208
|
|
|
208
|
|
609
|
use List::Util (); |
|
208
|
|
|
|
|
236
|
|
|
208
|
|
|
|
|
2931
|
|
7
|
208
|
|
|
208
|
|
39578
|
use Module::Runtime (); |
|
208
|
|
|
|
|
115997
|
|
|
208
|
|
|
|
|
3858
|
|
8
|
208
|
|
|
208
|
|
733
|
use Scalar::Util (); |
|
208
|
|
|
|
|
1435
|
|
|
208
|
|
|
|
|
6713
|
|
9
|
|
|
|
|
|
|
|
10
|
|
|
|
|
|
|
# This (and relevant tests) can disappear if UtilsBy gains XS: |
11
|
|
|
|
|
|
|
our $UsingUtilsByXS = 0; |
12
|
208
|
|
|
208
|
|
1910
|
{ no warnings 'once'; |
|
208
|
|
|
|
|
240
|
|
|
208
|
|
|
|
|
76610
|
|
13
|
|
|
|
|
|
|
if (eval {; require List::UtilsBy::XS; 1 } && !$@) { |
14
|
|
|
|
|
|
|
$UsingUtilsByXS = 1; |
15
|
|
|
|
|
|
|
*__sort_by = \&List::UtilsBy::XS::sort_by; |
16
|
|
|
|
|
|
|
*__nsort_by = \&List::UtilsBy::XS::nsort_by; |
17
|
|
|
|
|
|
|
*__uniq_by = \&List::UtilsBy::XS::uniq_by; |
18
|
|
|
|
|
|
|
} else { |
19
|
|
|
|
|
|
|
require List::UtilsBy; |
20
|
|
|
|
|
|
|
*__sort_by = \&List::UtilsBy::sort_by; |
21
|
|
|
|
|
|
|
*__nsort_by = \&List::UtilsBy::nsort_by; |
22
|
|
|
|
|
|
|
*__uniq_by = \&List::UtilsBy::uniq_by; |
23
|
|
|
|
|
|
|
} |
24
|
|
|
|
|
|
|
} |
25
|
|
|
|
|
|
|
|
26
|
|
|
|
|
|
|
|
27
|
|
|
|
|
|
|
=for Pod::Coverage ARRAY_TYPE blessed_or_pkg |
28
|
|
|
|
|
|
|
|
29
|
|
|
|
|
|
|
=begin comment |
30
|
|
|
|
|
|
|
|
31
|
|
|
|
|
|
|
Regarding blessed_or_pkg(): |
32
|
|
|
|
|
|
|
This is some nonsense to support autoboxing; if we aren't blessed, we're |
33
|
|
|
|
|
|
|
autoboxed, in which case we appear to have no choice but to cheap out and |
34
|
|
|
|
|
|
|
return the basic array type. |
35
|
|
|
|
|
|
|
|
36
|
|
|
|
|
|
|
This should only be called to get your hands on ->new(). |
37
|
|
|
|
|
|
|
|
38
|
|
|
|
|
|
|
->new() methods should be able to operate on a blessed invocant. |
39
|
|
|
|
|
|
|
|
40
|
|
|
|
|
|
|
=end comment |
41
|
|
|
|
|
|
|
|
42
|
|
|
|
|
|
|
=cut |
43
|
|
|
|
|
|
|
|
44
|
|
|
|
|
|
|
sub ARRAY_TYPE () { 'List::Objects::WithUtils::Array' } |
45
|
|
|
|
|
|
|
|
46
|
|
|
|
|
|
|
sub blessed_or_pkg { |
47
|
265
|
100
|
|
265
|
0
|
1169
|
Scalar::Util::blessed($_[0]) ? |
48
|
|
|
|
|
|
|
$_[0] : Module::Runtime::use_module(ARRAY_TYPE) |
49
|
|
|
|
|
|
|
} |
50
|
|
|
|
|
|
|
|
51
|
|
|
|
|
|
|
|
52
|
|
|
|
|
|
|
sub __flatten_all { |
53
|
|
|
|
|
|
|
# __flatten optimized for max depth: |
54
|
|
|
|
|
|
|
ref $_[0] eq 'ARRAY' || Scalar::Util::blessed($_[0]) |
55
|
|
|
|
|
|
|
# 5.8 doesn't have ->DOES() |
56
|
|
|
|
|
|
|
&& $_[0]->can('does') |
57
|
|
|
|
|
|
|
&& $_[0]->does('List::Objects::WithUtils::Role::Array') ? |
58
|
45
|
100
|
66
|
45
|
|
260
|
map {; __flatten_all($_) } @{ $_[0] } |
|
28
|
|
|
|
|
37
|
|
|
10
|
|
|
|
|
2429
|
|
59
|
|
|
|
|
|
|
: $_[0] |
60
|
|
|
|
|
|
|
} |
61
|
|
|
|
|
|
|
|
62
|
|
|
|
|
|
|
sub __flatten { |
63
|
29
|
|
|
29
|
|
1447
|
my $depth = shift; |
64
|
|
|
|
|
|
|
CORE::map { |
65
|
29
|
100
|
66
|
|
|
41
|
ref eq 'ARRAY' || Scalar::Util::blessed($_) |
|
79
|
100
|
|
|
|
393
|
|
66
|
|
|
|
|
|
|
&& $_->can('does') |
67
|
|
|
|
|
|
|
&& $_->does('List::Objects::WithUtils::Role::Array') ? |
68
|
|
|
|
|
|
|
$depth > 0 ? __flatten( $depth - 1, @$_ ) : $_ |
69
|
|
|
|
|
|
|
: $_ |
70
|
|
|
|
|
|
|
} @_ |
71
|
|
|
|
|
|
|
} |
72
|
|
|
|
|
|
|
|
73
|
|
|
|
|
|
|
|
74
|
208
|
|
|
208
|
|
873
|
use Role::Tiny; # my position relative to subs matters |
|
208
|
|
|
|
|
1669
|
|
|
208
|
|
|
|
|
2785
|
|
75
|
|
|
|
|
|
|
|
76
|
|
|
|
|
|
|
|
77
|
20
|
|
|
20
|
1
|
84
|
sub inflated_type { 'List::Objects::WithUtils::Hash' } |
78
|
|
|
|
|
|
|
|
79
|
2
|
|
|
2
|
1
|
7
|
sub is_mutable { 1 } |
80
|
2
|
|
|
2
|
1
|
19
|
sub is_immutable { ! $_[0]->is_mutable } |
81
|
|
|
|
|
|
|
|
82
|
|
|
|
|
|
|
sub _try_coerce { |
83
|
|
|
|
|
|
|
# subclass-mungable (keep me under the Role::Tiny import) |
84
|
9
|
|
|
9
|
|
14
|
my (undef, $type, @vals) = @_; |
85
|
9
|
50
|
|
|
|
22
|
Carp::confess "Expected a Type::Tiny type but got $type" |
86
|
|
|
|
|
|
|
unless Scalar::Util::blessed $type; |
87
|
|
|
|
|
|
|
|
88
|
9
|
|
|
|
|
8
|
CORE::map {; |
89
|
9
|
|
|
|
|
5
|
my $coerced; |
90
|
9
|
50
|
|
|
|
16
|
$type->check($_) ? $_ |
|
|
0
|
|
|
|
|
|
|
|
100
|
|
|
|
|
|
91
|
|
|
|
|
|
|
: $type->assert_valid( |
92
|
|
|
|
|
|
|
$type->has_coercion ? ($coerced = $type->coerce($_)) : $_ |
93
|
|
|
|
|
|
|
) ? $coerced |
94
|
|
|
|
|
|
|
: Carp::confess "I should be unreachable!" |
95
|
|
|
|
|
|
|
} @vals |
96
|
|
|
|
|
|
|
} |
97
|
|
|
|
|
|
|
|
98
|
|
|
|
|
|
|
|
99
|
|
|
|
|
|
|
=for Pod::Coverage TO_JSON TO_ZPL damn type |
100
|
|
|
|
|
|
|
|
101
|
|
|
|
|
|
|
=cut |
102
|
|
|
|
|
|
|
|
103
|
|
|
|
3
|
0
|
|
sub type { |
104
|
|
|
|
|
|
|
# array() has an empty ->type |
105
|
|
|
|
|
|
|
} |
106
|
|
|
|
|
|
|
|
107
|
836
|
|
66
|
836
|
1
|
6809
|
sub new { bless [ @_[1 .. $#_ ] ], Scalar::Util::blessed($_[0]) || $_[0] } |
108
|
|
|
|
|
|
|
|
109
|
|
|
|
|
|
|
|
110
|
|
|
|
|
|
|
=for Pod::Coverage untyped |
111
|
|
|
|
|
|
|
|
112
|
|
|
|
|
|
|
=cut |
113
|
|
|
|
|
|
|
|
114
|
208
|
|
|
208
|
|
73019
|
{ no warnings 'once'; *untyped = *copy } |
|
208
|
|
|
|
|
276
|
|
|
208
|
|
|
|
|
25622
|
|
115
|
7
|
|
|
7
|
1
|
2803
|
sub copy { blessed_or_pkg($_[0])->new(@{ $_[0] }) } |
|
7
|
|
|
|
|
97
|
|
116
|
|
|
|
|
|
|
|
117
|
|
|
|
|
|
|
sub inflate { |
118
|
8
|
|
|
8
|
1
|
37
|
my ($self) = @_; |
119
|
8
|
|
|
|
|
20
|
my $cls = blessed_or_pkg($self); |
120
|
8
|
|
|
|
|
61
|
Module::Runtime::require_module( $cls->inflated_type ); |
121
|
8
|
|
|
|
|
130
|
$cls->inflated_type->new(@$self) |
122
|
|
|
|
|
|
|
} |
123
|
|
|
|
|
|
|
|
124
|
208
|
|
|
208
|
|
779
|
{ no warnings 'once'; |
|
208
|
|
|
|
|
241
|
|
|
208
|
|
|
|
|
29326
|
|
125
|
|
|
|
|
|
|
*TO_JSON = *unbless; |
126
|
|
|
|
|
|
|
*TO_ZPL = *unbless; |
127
|
|
|
|
|
|
|
*damn = *unbless; |
128
|
|
|
|
|
|
|
} |
129
|
10
|
|
|
10
|
1
|
1810
|
sub unbless { [ @{ $_[0] } ] } |
|
10
|
|
|
|
|
36
|
|
130
|
|
|
|
|
|
|
|
131
|
|
|
|
|
|
|
sub validated { |
132
|
3
|
|
|
3
|
1
|
2659
|
my ($self, $type) = @_; |
133
|
|
|
|
|
|
|
# Autoboxed? |
134
|
3
|
100
|
|
|
|
11
|
$self = blessed_or_pkg($self)->new(@$self) |
135
|
|
|
|
|
|
|
unless Scalar::Util::blessed $self; |
136
|
|
|
|
|
|
|
blessed_or_pkg($_[0])->new( |
137
|
3
|
|
|
|
|
6
|
CORE::map {; $self->_try_coerce($type, $_) } @$self |
|
9
|
|
|
|
|
73
|
|
138
|
|
|
|
|
|
|
) |
139
|
|
|
|
|
|
|
} |
140
|
|
|
|
|
|
|
|
141
|
246
|
|
|
246
|
1
|
9979
|
sub all { @{ $_[0] } } |
|
246
|
|
|
|
|
1408
|
|
142
|
208
|
|
|
208
|
|
877
|
{ no warnings 'once'; *export = *all; *elements = *all; } |
|
208
|
|
|
|
|
253
|
|
|
208
|
|
|
|
|
12752
|
|
143
|
|
|
|
|
|
|
|
144
|
|
|
|
|
|
|
|
145
|
|
|
|
|
|
|
=for Pod::Coverage size |
146
|
|
|
|
|
|
|
|
147
|
|
|
|
|
|
|
=cut |
148
|
|
|
|
|
|
|
|
149
|
57
|
|
|
57
|
1
|
9324
|
sub count { CORE::scalar @{ $_[0] } } |
|
57
|
|
|
|
|
251
|
|
150
|
208
|
|
|
208
|
|
723
|
{ no warnings 'once'; *scalar = *count; *size = *count; } |
|
208
|
|
|
|
|
237
|
|
|
208
|
|
|
|
|
200019
|
|
151
|
|
|
|
|
|
|
|
152
|
4
|
|
|
4
|
1
|
19
|
sub end { $#{ $_[0] } } |
|
4
|
|
|
|
|
21
|
|
153
|
|
|
|
|
|
|
|
154
|
68
|
|
|
68
|
1
|
1385
|
sub is_empty { ! @{ $_[0] } } |
|
68
|
|
|
|
|
280
|
|
155
|
|
|
|
|
|
|
|
156
|
|
|
|
|
|
|
sub exists { |
157
|
21
|
|
|
21
|
1
|
45
|
my $r; |
158
|
|
|
|
|
|
|
!!( |
159
|
21
|
|
|
|
|
145
|
$_[1] <= $#{ $_[0] } ? $_[1] >= 0 ? 1 |
160
|
21
|
100
|
66
|
|
|
21
|
: (($r = $_[1] + @{ $_[0] }) <= $#{ $_[0] } && $r >= 0) ? 1 : () |
|
|
100
|
|
|
|
|
|
|
|
100
|
|
|
|
|
|
161
|
|
|
|
|
|
|
: () |
162
|
|
|
|
|
|
|
) |
163
|
|
|
|
|
|
|
} |
164
|
|
|
|
|
|
|
|
165
|
6
|
|
|
6
|
1
|
42
|
sub defined { defined $_[0]->[ $_[1] ] } |
166
|
|
|
|
|
|
|
|
167
|
44
|
|
|
44
|
1
|
554
|
sub get { $_[0]->[ $_[1] ] } |
168
|
|
|
|
|
|
|
|
169
|
|
|
|
|
|
|
sub get_or_else { |
170
|
8
|
100
|
100
|
8
|
1
|
118
|
defined $_[0]->[ $_[1] ] ? $_[0]->[ $_[1] ] |
|
|
100
|
|
|
|
|
|
171
|
|
|
|
|
|
|
: (Scalar::Util::reftype $_[2] || '') eq 'CODE' ? $_[2]->(@_[0,1]) |
172
|
|
|
|
|
|
|
: $_[2] |
173
|
|
|
|
|
|
|
} |
174
|
|
|
|
|
|
|
|
175
|
7
|
|
|
7
|
1
|
710
|
sub set { $_[0]->[ $_[1] ] = $_[2] ; $_[0] } |
|
6
|
|
|
|
|
30
|
|
176
|
|
|
|
|
|
|
|
177
|
4
|
|
|
4
|
1
|
22
|
sub random { $_[0]->[ rand @{ $_[0] } ] } |
|
4
|
|
|
|
|
96
|
|
178
|
|
|
|
|
|
|
|
179
|
|
|
|
|
|
|
sub kv { |
180
|
3
|
|
|
3
|
1
|
21
|
my ($self) = @_; |
181
|
|
|
|
|
|
|
blessed_or_pkg($self)->new( |
182
|
3
|
|
|
|
|
7
|
map {; [ $_ => $self->[$_] ] } 0 .. $#$self |
|
8
|
|
|
|
|
46
|
|
183
|
|
|
|
|
|
|
) |
184
|
|
|
|
|
|
|
} |
185
|
|
|
|
|
|
|
|
186
|
|
|
|
|
|
|
sub head { |
187
|
|
|
|
|
|
|
wantarray ? |
188
|
|
|
|
|
|
|
( |
189
|
|
|
|
|
|
|
$_[0]->[0], |
190
|
6
|
100
|
|
6
|
1
|
1239
|
blessed_or_pkg($_[0])->new( @{ $_[0] }[ 1 .. $#{$_[0]} ] ) |
|
3
|
|
|
|
|
12
|
|
|
3
|
|
|
|
|
35
|
|
191
|
|
|
|
|
|
|
) |
192
|
|
|
|
|
|
|
: $_[0]->[0] |
193
|
|
|
|
|
|
|
} |
194
|
|
|
|
|
|
|
|
195
|
|
|
|
|
|
|
sub tail { |
196
|
|
|
|
|
|
|
wantarray ? |
197
|
|
|
|
|
|
|
( |
198
|
|
|
|
|
|
|
$_[0]->[-1], |
199
|
6
|
100
|
|
6
|
1
|
1162
|
blessed_or_pkg($_[0])->new( @{ $_[0] }[ 0 .. ($#{$_[0]} - 1) ] ) |
|
3
|
|
|
|
|
8
|
|
|
3
|
|
|
|
|
36
|
|
200
|
|
|
|
|
|
|
) |
201
|
|
|
|
|
|
|
: $_[0]->[-1] |
202
|
|
|
|
|
|
|
} |
203
|
|
|
|
|
|
|
|
204
|
4
|
|
|
4
|
1
|
14
|
sub pop { CORE::pop @{ $_[0] } } |
|
4
|
|
|
|
|
20
|
|
205
|
|
|
|
|
|
|
sub push { |
206
|
14
|
|
|
14
|
1
|
876
|
CORE::push @{ $_[0] }, @_[1 .. $#_]; |
|
14
|
|
|
|
|
72
|
|
207
|
13
|
|
|
|
|
45
|
$_[0] |
208
|
|
|
|
|
|
|
} |
209
|
|
|
|
|
|
|
|
210
|
4
|
|
|
4
|
1
|
21
|
sub shift { CORE::shift @{ $_[0] } } |
|
4
|
|
|
|
|
18
|
|
211
|
|
|
|
|
|
|
sub unshift { |
212
|
6
|
|
|
6
|
1
|
680
|
CORE::unshift @{ $_[0] }, @_[1 .. $#_]; |
|
6
|
|
|
|
|
25
|
|
213
|
5
|
|
|
|
|
37
|
$_[0] |
214
|
|
|
|
|
|
|
} |
215
|
|
|
|
|
|
|
|
216
|
4
|
|
|
4
|
1
|
31
|
sub clear { @{ $_[0] } = (); $_[0] } |
|
4
|
|
|
|
|
13
|
|
|
4
|
|
|
|
|
14
|
|
217
|
|
|
|
|
|
|
|
218
|
4
|
|
|
4
|
1
|
31
|
sub delete { scalar CORE::splice @{ $_[0] }, $_[1], 1 } |
|
4
|
|
|
|
|
28
|
|
219
|
|
|
|
|
|
|
|
220
|
|
|
|
|
|
|
sub delete_when { |
221
|
8
|
|
|
8
|
1
|
39
|
my ($self, $cb) = @_; |
222
|
8
|
|
|
|
|
8
|
my @removed; |
223
|
8
|
|
|
|
|
12
|
my $i = @$self; |
224
|
8
|
|
|
|
|
22
|
while ($i--) { |
225
|
24
|
|
|
|
|
85
|
local *_ = \$self->[$i]; |
226
|
24
|
100
|
|
|
|
34
|
CORE::push @removed, CORE::splice @$self, $i, 1 if $cb->($_); |
227
|
|
|
|
|
|
|
} |
228
|
8
|
|
|
|
|
36
|
blessed_or_pkg($_[0])->new(@removed) |
229
|
|
|
|
|
|
|
} |
230
|
|
|
|
|
|
|
|
231
|
|
|
|
|
|
|
sub insert { |
232
|
13
|
100
|
|
13
|
1
|
439
|
$#{$_[0]} = ($_[1]-1) if $_[1] > $#{$_[0]}; |
|
6
|
|
|
|
|
19
|
|
|
13
|
|
|
|
|
67
|
|
233
|
13
|
|
|
|
|
27
|
CORE::splice @{ $_[0] }, $_[1], 0, @_[2 .. $#_]; |
|
13
|
|
|
|
|
62
|
|
234
|
12
|
|
|
|
|
50
|
$_[0] |
235
|
|
|
|
|
|
|
} |
236
|
|
|
|
|
|
|
|
237
|
|
|
|
|
|
|
sub intersection { |
238
|
6
|
|
|
6
|
1
|
27
|
my %seen; |
239
|
|
|
|
|
|
|
blessed_or_pkg($_[0])->new( |
240
|
|
|
|
|
|
|
# Well. Probably not the most efficient approach . . . |
241
|
57
|
|
|
|
|
65
|
CORE::grep {; ++$seen{$_} > $#_ } |
242
|
6
|
|
|
|
|
15
|
CORE::map {; |
243
|
14
|
|
|
|
|
44
|
my %s = (); CORE::grep {; not $s{$_}++ } @$_ |
|
14
|
|
|
|
|
21
|
|
|
58
|
|
|
|
|
92
|
|
244
|
|
|
|
|
|
|
} @_ |
245
|
|
|
|
|
|
|
) |
246
|
|
|
|
|
|
|
} |
247
|
|
|
|
|
|
|
|
248
|
|
|
|
|
|
|
sub diff { |
249
|
10
|
|
|
10
|
1
|
33
|
my %seen; |
250
|
10
|
|
|
|
|
15
|
my @vals = CORE::map {; |
251
|
21
|
|
|
|
|
25
|
my %s = (); CORE::grep {; not $s{$_}++ } @$_ |
|
21
|
|
|
|
|
29
|
|
|
60
|
|
|
|
|
130
|
|
252
|
|
|
|
|
|
|
} @_; |
253
|
10
|
|
|
|
|
40
|
$seen{$_}++ for @vals; |
254
|
10
|
|
|
|
|
12
|
my %inner; |
255
|
|
|
|
|
|
|
blessed_or_pkg($_[0])->new( |
256
|
40
|
|
|
|
|
56
|
CORE::grep {; $seen{$_} != @_ } |
257
|
10
|
|
|
|
|
27
|
CORE::grep {; not $inner{$_}++ } @vals |
|
60
|
|
|
|
|
141
|
|
258
|
|
|
|
|
|
|
) |
259
|
|
|
|
|
|
|
} |
260
|
|
|
|
|
|
|
|
261
|
|
|
|
|
|
|
sub join { |
262
|
|
|
|
|
|
|
CORE::join( |
263
|
|
|
|
|
|
|
( defined $_[1] ? $_[1] : ',' ), |
264
|
8
|
100
|
|
8
|
1
|
27
|
@{ $_[0] } |
|
8
|
|
|
|
|
41
|
|
265
|
|
|
|
|
|
|
) |
266
|
|
|
|
|
|
|
} |
267
|
|
|
|
|
|
|
|
268
|
|
|
|
|
|
|
sub map { |
269
|
|
|
|
|
|
|
blessed_or_pkg($_[0])->new( |
270
|
13
|
|
|
13
|
1
|
888
|
CORE::map {; $_[1]->($_) } @{ $_[0] } |
|
51
|
|
|
|
|
162
|
|
|
13
|
|
|
|
|
162
|
|
271
|
|
|
|
|
|
|
) |
272
|
|
|
|
|
|
|
} |
273
|
|
|
|
|
|
|
|
274
|
|
|
|
|
|
|
sub mapval { |
275
|
6
|
|
|
6
|
1
|
27
|
my ($self, $cb) = @_; |
276
|
6
|
|
|
|
|
10
|
my @copy = @$self; |
277
|
|
|
|
|
|
|
blessed_or_pkg($self)->new( |
278
|
6
|
|
|
|
|
14
|
CORE::map {; $cb->($_); $_ } @copy |
|
12
|
|
|
|
|
62
|
|
|
12
|
|
|
|
|
28
|
|
279
|
|
|
|
|
|
|
) |
280
|
|
|
|
|
|
|
} |
281
|
|
|
|
|
|
|
|
282
|
|
|
|
|
|
|
sub visit { |
283
|
4
|
|
|
4
|
1
|
832
|
$_[1]->($_) for @{ $_[0] }; |
|
4
|
|
|
|
|
16
|
|
284
|
4
|
|
|
|
|
16
|
$_[0] |
285
|
|
|
|
|
|
|
} |
286
|
|
|
|
|
|
|
|
287
|
|
|
|
|
|
|
sub grep { |
288
|
|
|
|
|
|
|
blessed_or_pkg($_[0])->new( |
289
|
7
|
|
|
7
|
1
|
42
|
CORE::grep {; $_[1]->($_) } @{ $_[0] } |
|
19
|
|
|
|
|
48
|
|
|
7
|
|
|
|
|
81
|
|
290
|
|
|
|
|
|
|
) |
291
|
|
|
|
|
|
|
} |
292
|
|
|
|
|
|
|
|
293
|
|
|
|
|
|
|
|
294
|
|
|
|
|
|
|
|
295
|
|
|
|
|
|
|
=for Pod::Coverage indices |
296
|
|
|
|
|
|
|
|
297
|
|
|
|
|
|
|
=cut |
298
|
|
|
|
|
|
|
|
299
|
208
|
|
|
208
|
|
939
|
{ no warnings 'once'; *indices = *indexes; } |
|
208
|
|
|
|
|
268
|
|
|
208
|
|
|
|
|
26019
|
|
300
|
|
|
|
|
|
|
sub indexes { |
301
|
|
|
|
|
|
|
$_[1] ? |
302
|
|
|
|
|
|
|
blessed_or_pkg($_[0])->new( |
303
|
32
|
|
|
|
|
75
|
grep {; local *_ = \$_[0]->[$_]; $_[1]->() } 0 .. $#{ $_[0] } |
|
32
|
|
|
|
|
38
|
|
|
8
|
|
|
|
|
101
|
|
304
|
|
|
|
|
|
|
) |
305
|
10
|
100
|
|
10
|
1
|
51
|
: blessed_or_pkg($_[0])->new( 0 .. $#{ $_[0] } ) |
|
2
|
|
|
|
|
26
|
|
306
|
|
|
|
|
|
|
} |
307
|
|
|
|
|
|
|
|
308
|
|
|
|
|
|
|
sub sort { |
309
|
37
|
100
|
66
|
37
|
1
|
1201
|
if (defined $_[1] && (my $cb = $_[1])) { |
310
|
12
|
|
|
|
|
30
|
my $pkg = caller; |
311
|
208
|
|
|
208
|
|
892
|
no strict 'refs'; |
|
208
|
|
|
|
|
309
|
|
|
208
|
|
|
|
|
32334
|
|
312
|
|
|
|
|
|
|
return blessed_or_pkg($_[0])->new( |
313
|
|
|
|
|
|
|
CORE::sort {; |
314
|
43
|
|
|
|
|
114
|
local (*{"${pkg}::a"}, *{"${pkg}::b"}) = (\$a, \$b); |
|
43
|
|
|
|
|
61
|
|
|
43
|
|
|
|
|
64
|
|
315
|
43
|
|
|
|
|
62
|
$a->$cb($b) |
316
|
12
|
|
|
|
|
31
|
} @{ $_[0] } |
|
12
|
|
|
|
|
84
|
|
317
|
|
|
|
|
|
|
) |
318
|
|
|
|
|
|
|
} |
319
|
25
|
|
|
|
|
54
|
blessed_or_pkg($_[0])->new( CORE::sort @{ $_[0] } ) |
|
25
|
|
|
|
|
137
|
|
320
|
|
|
|
|
|
|
} |
321
|
|
|
|
|
|
|
|
322
|
|
|
|
|
|
|
sub reverse { |
323
|
4
|
|
|
4
|
1
|
27
|
blessed_or_pkg($_[0])->new( CORE::reverse @{ $_[0] } ) |
|
4
|
|
|
|
|
60
|
|
324
|
|
|
|
|
|
|
} |
325
|
|
|
|
|
|
|
|
326
|
|
|
|
|
|
|
|
327
|
|
|
|
|
|
|
=for Pod::Coverage slice |
328
|
|
|
|
|
|
|
|
329
|
|
|
|
|
|
|
=cut |
330
|
|
|
|
|
|
|
|
331
|
208
|
|
|
208
|
|
822
|
{ no warnings 'once'; *slice = *sliced } |
|
208
|
|
|
|
|
220
|
|
|
208
|
|
|
|
|
33881
|
|
332
|
|
|
|
|
|
|
sub sliced { |
333
|
6
|
|
|
6
|
1
|
30
|
my @safe = @{ $_[0] }; |
|
6
|
|
|
|
|
15
|
|
334
|
6
|
|
|
|
|
14
|
blessed_or_pkg($_[0])->new( @safe[ @_[1 .. $#_] ] ) |
335
|
|
|
|
|
|
|
} |
336
|
|
|
|
|
|
|
|
337
|
|
|
|
|
|
|
sub splice { |
338
|
|
|
|
|
|
|
blessed_or_pkg($_[0])->new( |
339
|
2
|
|
|
|
|
62
|
@_ == 2 ? CORE::splice( @{ $_[0] }, $_[1] ) |
340
|
8
|
100
|
|
8
|
1
|
452
|
: CORE::splice( @{ $_[0] }, $_[1], $_[2], @_[3 .. $#_] ) |
|
6
|
|
|
|
|
45
|
|
341
|
|
|
|
|
|
|
) |
342
|
|
|
|
|
|
|
} |
343
|
|
|
|
|
|
|
|
344
|
|
|
|
|
|
|
sub has_any { |
345
|
15
|
|
|
|
|
88
|
defined $_[1] ? !! &List::Util::any( $_[1], @{ $_[0] } ) |
346
|
27
|
100
|
|
27
|
1
|
754
|
: !! @{ $_[0] } |
|
12
|
|
|
|
|
53
|
|
347
|
|
|
|
|
|
|
} |
348
|
|
|
|
|
|
|
|
349
|
|
|
|
|
|
|
|
350
|
|
|
|
|
|
|
=for Pod::Coverage first |
351
|
|
|
|
|
|
|
|
352
|
|
|
|
|
|
|
=cut |
353
|
|
|
|
|
|
|
|
354
|
208
|
|
|
208
|
|
803
|
{ no warnings 'once'; *first = *first_where } |
|
208
|
|
|
|
|
238
|
|
|
208
|
|
|
|
|
27544
|
|
355
|
5
|
|
|
5
|
1
|
1196
|
sub first_where { &List::Util::first( $_[1], @{ $_[0] } ) } |
|
5
|
|
|
|
|
58
|
|
356
|
|
|
|
|
|
|
|
357
|
|
|
|
|
|
|
sub last_where { |
358
|
8
|
|
|
8
|
1
|
42
|
my ($self, $cb) = @_; |
359
|
8
|
|
|
|
|
12
|
my $i = @$self; |
360
|
8
|
|
|
|
|
22
|
while ($i--) { |
361
|
19
|
|
|
|
|
21
|
local *_ = \$self->[$i]; |
362
|
19
|
|
|
|
|
28
|
my $ret = $cb->(); |
363
|
19
|
|
|
|
|
60
|
$self->[$i] = $_; |
364
|
19
|
100
|
|
|
|
56
|
return $_ if $ret; |
365
|
|
|
|
|
|
|
} |
366
|
|
|
|
|
|
|
undef |
367
|
4
|
|
|
|
|
19
|
} |
368
|
|
|
|
|
|
|
|
369
|
208
|
|
|
208
|
|
807
|
{ no warnings 'once'; |
|
208
|
|
|
|
|
233
|
|
|
208
|
|
|
|
|
30649
|
|
370
|
|
|
|
|
|
|
*first_index = *firstidx; |
371
|
|
|
|
|
|
|
*last_index = *lastidx; |
372
|
|
|
|
|
|
|
} |
373
|
|
|
|
|
|
|
sub firstidx { |
374
|
9
|
|
|
9
|
1
|
1221
|
my ($self, $cb) = @_; |
375
|
9
|
|
|
|
|
30
|
for my $i (0 .. $#$self) { |
376
|
20
|
|
|
|
|
73
|
local *_ = \$self->[$i]; |
377
|
20
|
100
|
|
|
|
28
|
return $i if $cb->(); |
378
|
|
|
|
|
|
|
} |
379
|
4
|
|
|
|
|
17
|
-1 |
380
|
|
|
|
|
|
|
} |
381
|
|
|
|
|
|
|
|
382
|
|
|
|
|
|
|
sub lastidx { |
383
|
7
|
|
|
7
|
1
|
30
|
my ($self, $cb) = @_; |
384
|
7
|
|
|
|
|
19
|
for my $i (CORE::reverse 0 .. $#$self) { |
385
|
14
|
|
|
|
|
42
|
local *_ = \$self->[$i]; |
386
|
14
|
100
|
|
|
|
18
|
return $i if $cb->(); |
387
|
|
|
|
|
|
|
} |
388
|
4
|
|
|
|
|
24
|
-1 |
389
|
|
|
|
|
|
|
} |
390
|
|
|
|
|
|
|
|
391
|
208
|
|
|
208
|
|
1800
|
{ no warnings 'once'; *zip = *mesh; } |
|
208
|
|
|
|
|
265
|
|
|
208
|
|
|
|
|
158056
|
|
392
|
|
|
|
|
|
|
sub mesh { |
393
|
8
|
|
|
8
|
1
|
8
|
my $max_idx = -1; |
394
|
8
|
100
|
|
|
|
17
|
for (@_) { $max_idx = $#$_ if $max_idx < $#$_ } |
|
19
|
|
|
|
|
51
|
|
395
|
|
|
|
|
|
|
blessed_or_pkg($_[0])->new( |
396
|
7
|
|
|
|
|
16
|
CORE::map {; |
397
|
25
|
|
|
|
|
44
|
my $idx = $_; map {; $_->[$idx] } @_ |
|
25
|
|
|
|
|
20
|
|
|
53
|
|
|
|
|
56
|
|
398
|
|
|
|
|
|
|
} 0 .. $max_idx |
399
|
|
|
|
|
|
|
) |
400
|
|
|
|
|
|
|
} |
401
|
|
|
|
|
|
|
|
402
|
|
|
|
|
|
|
sub natatime { |
403
|
6
|
|
|
6
|
1
|
23
|
my @list = @{ $_[0] }; |
|
6
|
|
|
|
|
15
|
|
404
|
6
|
|
|
|
|
7
|
my $count = $_[1]; |
405
|
6
|
|
|
15
|
|
19
|
my $itr = sub { CORE::splice @list, 0, $count }; |
|
15
|
|
|
|
|
78
|
|
406
|
6
|
100
|
|
|
|
16
|
if (defined $_[2]) { |
407
|
2
|
|
|
|
|
6
|
while (my @nxt = $itr->()) { $_[2]->(@nxt) } |
|
6
|
|
|
|
|
10
|
|
408
|
|
|
|
|
|
|
return |
409
|
2
|
|
|
|
|
6
|
} |
410
|
|
|
|
|
|
|
$itr |
411
|
4
|
|
|
|
|
6
|
} |
412
|
|
|
|
|
|
|
|
413
|
|
|
|
|
|
|
sub rotator { |
414
|
4
|
|
|
4
|
1
|
23
|
my @list = @{ $_[0] }; |
|
4
|
|
|
|
|
12
|
|
415
|
4
|
|
|
|
|
7
|
my $pos = 0; |
416
|
|
|
|
|
|
|
sub { |
417
|
16
|
|
|
16
|
|
45
|
my $val = $list[$pos++]; |
418
|
16
|
100
|
|
|
|
27
|
$pos = 0 if $pos == @list; |
419
|
16
|
|
|
|
|
29
|
$val |
420
|
|
|
|
|
|
|
} |
421
|
4
|
|
|
|
|
19
|
} |
422
|
|
|
|
|
|
|
|
423
|
|
|
|
|
|
|
sub part { |
424
|
4
|
|
|
4
|
1
|
19
|
my ($self, $code) = @_; |
425
|
4
|
|
|
|
|
6
|
my @parts; |
426
|
4
|
|
|
|
|
12
|
CORE::push @{ $parts[ $code->($_) ] }, $_ for @$self; |
|
36
|
|
|
|
|
110
|
|
427
|
4
|
|
|
|
|
18
|
my $cls = blessed_or_pkg($self); |
428
|
|
|
|
|
|
|
$cls->new( |
429
|
4
|
100
|
|
|
|
33
|
map {; $cls->new(defined $_ ? @$_ : () ) } @parts |
|
11
|
|
|
|
|
31
|
|
430
|
|
|
|
|
|
|
) |
431
|
|
|
|
|
|
|
} |
432
|
|
|
|
|
|
|
|
433
|
|
|
|
|
|
|
sub part_to_hash { |
434
|
2
|
|
|
2
|
1
|
26
|
my ($self, $code) = @_; |
435
|
2
|
|
|
|
|
4
|
my %parts; |
436
|
2
|
|
|
|
|
8
|
CORE::push @{ $parts{ $code->($_) } }, $_ for @$self; |
|
10
|
|
|
|
|
38
|
|
437
|
2
|
|
|
|
|
10
|
my $cls = blessed_or_pkg($self); |
438
|
2
|
|
|
|
|
42
|
Module::Runtime::require_module( $cls->inflated_type ); |
439
|
2
|
|
|
|
|
18
|
@parts{keys %parts} = map {; $cls->new(@$_) } values %parts; |
|
6
|
|
|
|
|
13
|
|
440
|
2
|
|
|
|
|
7
|
$cls->inflated_type->new(%parts) |
441
|
|
|
|
|
|
|
} |
442
|
|
|
|
|
|
|
|
443
|
|
|
|
|
|
|
sub bisect { |
444
|
4
|
|
|
4
|
1
|
27
|
my ($self, $code) = @_; |
445
|
4
|
|
|
|
|
9
|
my @parts = ( [], [] ); |
446
|
4
|
100
|
|
|
|
11
|
CORE::push @{ $parts[ $code->($_) ? 0 : 1 ] }, $_ for @$self; |
|
20
|
|
|
|
|
64
|
|
447
|
4
|
|
|
|
|
13
|
my $cls = blessed_or_pkg($self); |
448
|
4
|
|
|
|
|
48
|
$cls->new( map {; $cls->new(@$_) } @parts ) |
|
8
|
|
|
|
|
15
|
|
449
|
|
|
|
|
|
|
} |
450
|
|
|
|
|
|
|
|
451
|
|
|
|
|
|
|
sub nsect { |
452
|
6
|
|
|
6
|
1
|
26
|
my ($self, $sections) = @_; |
453
|
6
|
|
|
|
|
12
|
my $total = scalar @$self; |
454
|
6
|
|
|
|
|
6
|
my @parts; |
455
|
6
|
|
|
|
|
5
|
my $x = 0; |
456
|
6
|
100
|
|
|
|
19
|
$sections = $total if (defined $sections ? $sections : 0) > $total; |
|
|
100
|
|
|
|
|
|
457
|
6
|
100
|
66
|
|
|
28
|
if ($sections && $total) { |
458
|
4
|
|
|
|
|
8
|
CORE::push @{ $parts[ int($x++ * $sections / $total) ] }, $_ for @$self; |
|
33
|
|
|
|
|
53
|
|
459
|
|
|
|
|
|
|
} |
460
|
6
|
|
|
|
|
12
|
my $cls = blessed_or_pkg($self); |
461
|
6
|
|
|
|
|
43
|
$cls->new( map {; $cls->new(@$_) } @parts ) |
|
10
|
|
|
|
|
18
|
|
462
|
|
|
|
|
|
|
} |
463
|
|
|
|
|
|
|
|
464
|
|
|
|
|
|
|
sub ssect { |
465
|
5
|
|
|
5
|
1
|
24
|
my ($self, $per) = @_; |
466
|
5
|
|
|
|
|
5
|
my @parts; |
467
|
5
|
|
|
|
|
6
|
my $x = 0; |
468
|
5
|
100
|
|
|
|
10
|
if ($per) { |
469
|
4
|
|
|
|
|
12
|
CORE::push @{ $parts[ int($x++ / $per) ] }, $_ for @$self; |
|
20
|
|
|
|
|
29
|
|
470
|
|
|
|
|
|
|
} |
471
|
5
|
|
|
|
|
11
|
my $cls = blessed_or_pkg($self); |
472
|
5
|
|
|
|
|
58
|
$cls->new( map {; $cls->new(@$_) } @parts ) |
|
8
|
|
|
|
|
14
|
|
473
|
|
|
|
|
|
|
} |
474
|
|
|
|
|
|
|
|
475
|
|
|
|
|
|
|
sub tuples { |
476
|
8
|
|
|
8
|
1
|
31
|
my ($self, $size, $type, $bless) = @_; |
477
|
8
|
100
|
|
|
|
16
|
$size = 2 unless defined $size; |
478
|
8
|
100
|
|
|
|
174
|
Carp::confess "Expected a positive integer size but got $size" |
479
|
|
|
|
|
|
|
if $size < 1; |
480
|
|
|
|
|
|
|
|
481
|
|
|
|
|
|
|
# Autoboxed? Need to be blessed if we're to _try_coerce: |
482
|
7
|
|
|
|
|
12
|
my $cls = blessed_or_pkg($self); |
483
|
7
|
50
|
33
|
|
|
46
|
$self = $cls->new(@$self) |
484
|
|
|
|
|
|
|
if defined $type and not Scalar::Util::blessed $self; |
485
|
|
|
|
|
|
|
|
486
|
7
|
|
|
|
|
7
|
my $itr = do { |
487
|
7
|
|
|
|
|
15
|
my @copy = @$self; |
488
|
25
|
|
|
25
|
|
46
|
sub { CORE::splice @copy, 0, $size } |
489
|
7
|
|
|
|
|
23
|
}; |
490
|
7
|
|
|
|
|
8
|
my @res; |
491
|
7
|
|
|
|
|
10
|
while (my @nxt = $itr->()) { |
492
|
18
|
50
|
|
|
|
22
|
@nxt = CORE::map {; $self->_try_coerce($type, $_) } @nxt |
|
0
|
|
|
|
|
0
|
|
493
|
|
|
|
|
|
|
if defined $type; |
494
|
18
|
100
|
|
|
|
41
|
CORE::push @res, $bless ? $cls->new(@nxt) : [ @nxt ]; |
495
|
|
|
|
|
|
|
} |
496
|
|
|
|
|
|
|
|
497
|
7
|
|
|
|
|
13
|
$cls->new(@res) |
498
|
|
|
|
|
|
|
} |
499
|
|
|
|
|
|
|
|
500
|
|
|
|
|
|
|
|
501
|
|
|
|
|
|
|
=for Pod::Coverage fold_left foldl fold_right |
502
|
|
|
|
|
|
|
|
503
|
|
|
|
|
|
|
=cut |
504
|
|
|
|
|
|
|
|
505
|
208
|
|
|
208
|
|
1179
|
{ no warnings 'once'; *foldl = *reduce; *fold_left = *reduce; } |
|
208
|
|
|
|
|
245
|
|
|
208
|
|
|
|
|
10415
|
|
506
|
|
|
|
|
|
|
sub reduce { |
507
|
10
|
|
|
10
|
1
|
658
|
my $pkg = caller; |
508
|
208
|
|
|
208
|
|
796
|
no strict 'refs'; |
|
208
|
|
|
|
|
849
|
|
|
208
|
|
|
|
|
20334
|
|
509
|
10
|
|
|
|
|
11
|
my $cb = $_[1]; |
510
|
|
|
|
|
|
|
List::Util::reduce { |
511
|
12
|
|
|
12
|
|
28
|
local (*{"${pkg}::a"}, *{"${pkg}::b"}) = (\$a, \$b); |
|
12
|
|
|
|
|
24
|
|
|
12
|
|
|
|
|
21
|
|
512
|
12
|
|
|
|
|
22
|
$a->$cb($b) |
513
|
10
|
|
|
|
|
29
|
} @{ $_[0] } |
|
10
|
|
|
|
|
68
|
|
514
|
|
|
|
|
|
|
} |
515
|
|
|
|
|
|
|
|
516
|
208
|
|
|
208
|
|
764
|
{ no warnings 'once'; *fold_right = *foldr; } |
|
208
|
|
|
|
|
243
|
|
|
208
|
|
|
|
|
9701
|
|
517
|
|
|
|
|
|
|
sub foldr { |
518
|
5
|
|
|
5
|
1
|
403
|
my $pkg = caller; |
519
|
208
|
|
|
208
|
|
689
|
no strict 'refs'; |
|
208
|
|
|
|
|
224
|
|
|
208
|
|
|
|
|
113798
|
|
520
|
5
|
|
|
|
|
8
|
my $cb = $_[1]; |
521
|
|
|
|
|
|
|
List::Util::reduce { |
522
|
6
|
|
|
6
|
|
18
|
local (*{"${pkg}::a"}, *{"${pkg}::b"}) = (\$b, \$a); |
|
6
|
|
|
|
|
16
|
|
|
6
|
|
|
|
|
13
|
|
523
|
6
|
|
|
|
|
16
|
$a->$cb($b) |
524
|
5
|
|
|
|
|
17
|
} CORE::reverse @{ $_[0] } |
|
5
|
|
|
|
|
27
|
|
525
|
|
|
|
|
|
|
} |
526
|
|
|
|
|
|
|
|
527
|
|
|
|
|
|
|
sub rotate { |
528
|
18
|
|
|
18
|
1
|
48
|
my ($self, %params) = @_; |
529
|
|
|
|
|
|
|
$params{left} && $params{right} ? |
530
|
|
|
|
|
|
|
Carp::confess "Cannot rotate in both directions!" |
531
|
|
|
|
|
|
|
: $params{right} ? |
532
|
|
|
|
|
|
|
blessed_or_pkg($self)->new( |
533
|
3
|
|
|
|
|
6
|
@$self ? ($self->[-1], @{ $self }[0 .. ($#$self - 1)]) : () |
534
|
|
|
|
|
|
|
) |
535
|
|
|
|
|
|
|
: blessed_or_pkg($self)->new( |
536
|
18
|
100
|
66
|
|
|
356
|
@$self ? (@{ $self }[1 .. $#$self], $self->[0]) : () |
|
10
|
100
|
|
|
|
126
|
|
|
|
100
|
|
|
|
|
|
|
|
100
|
|
|
|
|
|
537
|
|
|
|
|
|
|
) |
538
|
|
|
|
|
|
|
} |
539
|
|
|
|
|
|
|
|
540
|
|
|
|
|
|
|
sub rotate_in_place { |
541
|
7
|
100
|
|
7
|
1
|
507
|
$_[0] = Scalar::Util::blessed $_[0] ? |
542
|
|
|
|
|
|
|
$_[0]->rotate(@_[1 .. $#_]) : rotate(@_) |
543
|
|
|
|
|
|
|
} |
544
|
|
|
|
|
|
|
|
545
|
|
|
|
|
|
|
sub items_after { |
546
|
6
|
|
|
6
|
1
|
26
|
my ($started, $lag); |
547
|
|
|
|
|
|
|
blessed_or_pkg($_[0])->new( |
548
|
|
|
|
|
|
|
CORE::grep $started ||= do { |
549
|
22
|
|
|
|
|
20
|
my $x = $lag; $lag = $_[1]->(); $x |
|
22
|
|
|
|
|
32
|
|
|
22
|
|
|
|
|
91
|
|
550
|
6
|
|
100
|
|
|
14
|
}, @{ $_[0] } |
|
6
|
|
|
|
|
89
|
|
551
|
|
|
|
|
|
|
) |
552
|
|
|
|
|
|
|
} |
553
|
|
|
|
|
|
|
|
554
|
|
|
|
|
|
|
sub items_after_incl { |
555
|
6
|
|
|
6
|
1
|
26
|
my $started; |
556
|
|
|
|
|
|
|
blessed_or_pkg($_[0])->new( |
557
|
6
|
|
100
|
|
|
14
|
CORE::grep $started ||= $_[1]->(), @{ $_[0] } |
|
6
|
|
|
|
|
92
|
|
558
|
|
|
|
|
|
|
) |
559
|
|
|
|
|
|
|
} |
560
|
|
|
|
|
|
|
|
561
|
|
|
|
|
|
|
sub items_before { |
562
|
6
|
|
|
6
|
1
|
29
|
my $more = 1; |
563
|
|
|
|
|
|
|
blessed_or_pkg($_[0])->new( |
564
|
6
|
|
100
|
|
|
12
|
CORE::grep $more &&= !$_[1]->(), @{ $_[0] } |
|
6
|
|
|
|
|
105
|
|
565
|
|
|
|
|
|
|
) |
566
|
|
|
|
|
|
|
} |
567
|
|
|
|
|
|
|
|
568
|
|
|
|
|
|
|
sub items_before_incl { |
569
|
4
|
|
|
4
|
1
|
32
|
my $more = 1; my $lag = 1; |
|
4
|
|
|
|
|
5
|
|
570
|
|
|
|
|
|
|
blessed_or_pkg($_[0])->new( |
571
|
10
|
|
|
|
|
9
|
CORE::grep $more &&= do { my $x = $lag; $lag = !$_[1]->(); $x }, |
|
10
|
|
|
|
|
16
|
|
|
10
|
|
|
|
|
40
|
|
572
|
4
|
|
100
|
|
|
7
|
@{ $_[0] } |
|
4
|
|
|
|
|
62
|
|
573
|
|
|
|
|
|
|
) |
574
|
|
|
|
|
|
|
} |
575
|
|
|
|
|
|
|
|
576
|
|
|
|
|
|
|
sub pick { |
577
|
4
|
100
|
|
4
|
1
|
1719
|
return $_[0]->shuffle if $_[1] >= @{ $_[0] }; |
|
4
|
|
|
|
|
19
|
|
578
|
1
|
|
|
|
|
1
|
my %idx; |
579
|
1
|
|
|
|
|
3
|
$idx{ int rand @{ $_[0] } } = 1 until keys %idx == $_[1]; |
|
4
|
|
|
|
|
34
|
|
580
|
|
|
|
|
|
|
blessed_or_pkg($_[0])->new( |
581
|
1
|
|
|
|
|
3
|
@{ $_[0] }[keys %idx] |
|
1
|
|
|
|
|
3
|
|
582
|
|
|
|
|
|
|
) |
583
|
|
|
|
|
|
|
} |
584
|
|
|
|
|
|
|
|
585
|
|
|
|
|
|
|
sub roll { |
586
|
|
|
|
|
|
|
blessed_or_pkg($_[0])->new( |
587
|
3
|
|
|
|
|
8
|
@{ $_[0] }[ |
588
|
14
|
|
|
|
|
16
|
map {; int rand @{ $_[0] } } |
|
14
|
|
|
|
|
45
|
|
589
|
3
|
50
|
|
3
|
1
|
825
|
0 .. (defined $_[1] ? $_[1] : @{ $_[0] }) - 1 |
|
0
|
|
|
|
|
0
|
|
590
|
|
|
|
|
|
|
] |
591
|
|
|
|
|
|
|
) |
592
|
|
|
|
|
|
|
} |
593
|
|
|
|
|
|
|
|
594
|
|
|
|
|
|
|
sub shuffle { |
595
|
|
|
|
|
|
|
blessed_or_pkg($_[0])->new( |
596
|
6
|
|
|
6
|
1
|
31
|
List::Util::shuffle( @{ $_[0] } ) |
|
6
|
|
|
|
|
101
|
|
597
|
|
|
|
|
|
|
) |
598
|
|
|
|
|
|
|
} |
599
|
|
|
|
|
|
|
|
600
|
|
|
|
|
|
|
=for Pod::Coverage squish |
601
|
|
|
|
|
|
|
|
602
|
|
|
|
|
|
|
=cut |
603
|
|
|
|
|
|
|
|
604
|
208
|
|
|
208
|
|
879
|
{ no warnings 'once'; *squish = *squished; } |
|
208
|
|
|
|
|
239
|
|
|
208
|
|
|
|
|
106464
|
|
605
|
|
|
|
|
|
|
sub squished { |
606
|
|
|
|
|
|
|
# @last is a single-item array to make tracking undefs saner -> |
607
|
7
|
|
|
7
|
1
|
19
|
my (@last, @res); |
608
|
7
|
|
|
|
|
4
|
ITEM: for (@{ $_[0] }) { |
|
7
|
|
|
|
|
20
|
|
609
|
36
|
100
|
|
|
|
63
|
if (!@last) { |
|
|
100
|
|
|
|
|
|
|
|
100
|
|
|
|
|
|
610
|
|
|
|
|
|
|
# No items seen yet. |
611
|
6
|
|
|
|
|
7
|
$last[0] = $_; CORE::push @res, $_; next ITEM |
|
6
|
|
|
|
|
6
|
|
612
|
6
|
|
|
|
|
9
|
} elsif (!defined $_) { |
613
|
|
|
|
|
|
|
# Possibly two undefs in a row: |
614
|
4
|
100
|
|
|
|
8
|
next ITEM if not defined $last[0]; |
615
|
|
|
|
|
|
|
# .. or not: |
616
|
2
|
|
|
|
|
2
|
$last[0] = $_; CORE::push @res, $_; next ITEM |
|
2
|
|
|
|
|
2
|
|
617
|
2
|
|
|
|
|
2
|
} elsif (!defined $last[0]) { |
618
|
|
|
|
|
|
|
# Previous was an undef (but this isn't) |
619
|
4
|
|
|
|
|
2
|
$last[0] = $_; CORE::push @res, $_; next ITEM |
|
4
|
|
|
|
|
3
|
|
620
|
4
|
|
|
|
|
4
|
} |
621
|
22
|
100
|
|
|
|
27
|
next ITEM if $_ eq $last[0]; |
622
|
17
|
|
|
|
|
13
|
$last[0] = $_; CORE::push @res, $_; |
|
17
|
|
|
|
|
17
|
|
623
|
|
|
|
|
|
|
} |
624
|
7
|
|
|
|
|
12
|
blessed_or_pkg($_[0])->new(@res) |
625
|
|
|
|
|
|
|
} |
626
|
|
|
|
|
|
|
|
627
|
|
|
|
|
|
|
sub uniq { |
628
|
5
|
|
|
5
|
1
|
23
|
my %s; |
629
|
5
|
|
|
|
|
12
|
blessed_or_pkg($_[0])->new( CORE::grep {; not $s{$_}++ } @{ $_[0] } ) |
|
18
|
|
|
|
|
34
|
|
|
5
|
|
|
|
|
60
|
|
630
|
|
|
|
|
|
|
} |
631
|
|
|
|
|
|
|
|
632
|
|
|
|
|
|
|
sub repeated { |
633
|
3
|
|
|
3
|
1
|
6
|
my %s; |
634
|
3
|
|
|
|
|
7
|
blessed_or_pkg($_[0])->new( CORE::grep {; $s{$_}++ == 1 } @{ $_[0] } ) |
|
10
|
|
|
|
|
16
|
|
|
3
|
|
|
|
|
8
|
|
635
|
|
|
|
|
|
|
} |
636
|
|
|
|
|
|
|
|
637
|
|
|
|
|
|
|
sub sort_by { |
638
|
|
|
|
|
|
|
blessed_or_pkg($_[0])->new( |
639
|
10
|
|
|
10
|
1
|
593
|
__sort_by( $_[1], @{ $_[0] } ) |
|
10
|
|
|
|
|
151
|
|
640
|
|
|
|
|
|
|
) |
641
|
|
|
|
|
|
|
} |
642
|
|
|
|
|
|
|
|
643
|
|
|
|
|
|
|
sub nsort_by { |
644
|
|
|
|
|
|
|
blessed_or_pkg($_[0])->new( |
645
|
7
|
|
|
7
|
1
|
43
|
__nsort_by( $_[1], @{ $_[0] } ) |
|
7
|
|
|
|
|
97
|
|
646
|
|
|
|
|
|
|
) |
647
|
|
|
|
|
|
|
} |
648
|
|
|
|
|
|
|
|
649
|
|
|
|
|
|
|
sub uniq_by { |
650
|
|
|
|
|
|
|
blessed_or_pkg($_[0])->new( |
651
|
7
|
|
|
7
|
1
|
42
|
__uniq_by( $_[1], @{ $_[0] } ) |
|
7
|
|
|
|
|
96
|
|
652
|
|
|
|
|
|
|
) |
653
|
|
|
|
|
|
|
} |
654
|
|
|
|
|
|
|
|
655
|
|
|
|
|
|
|
sub flatten_all { |
656
|
7
|
|
|
7
|
1
|
39
|
CORE::map {; __flatten_all($_) } @{ $_[0] } |
|
17
|
|
|
|
|
22
|
|
|
7
|
|
|
|
|
29
|
|
657
|
|
|
|
|
|
|
} |
658
|
|
|
|
|
|
|
|
659
|
|
|
|
|
|
|
sub flatten { |
660
|
|
|
|
|
|
|
__flatten( |
661
|
|
|
|
|
|
|
( defined $_[1] ? $_[1] : 0 ), |
662
|
17
|
100
|
|
17
|
1
|
62
|
@{ $_[0] } |
|
17
|
|
|
|
|
42
|
|
663
|
|
|
|
|
|
|
) |
664
|
|
|
|
|
|
|
} |
665
|
|
|
|
|
|
|
|
666
|
|
|
|
|
|
|
print |
667
|
|
|
|
|
|
|
qq[ My sleeping pattern is cryptographically secure.\n] |
668
|
|
|
|
|
|
|
unless caller; |
669
|
|
|
|
|
|
|
1; |
670
|
|
|
|
|
|
|
|
671
|
|
|
|
|
|
|
=pod |
672
|
|
|
|
|
|
|
|
673
|
|
|
|
|
|
|
=head1 NAME |
674
|
|
|
|
|
|
|
|
675
|
|
|
|
|
|
|
List::Objects::WithUtils::Role::Array - Array manipulation methods |
676
|
|
|
|
|
|
|
|
677
|
|
|
|
|
|
|
=head1 SYNOPSIS |
678
|
|
|
|
|
|
|
|
679
|
|
|
|
|
|
|
## Via List::Objects::WithUtils::Array -> |
680
|
|
|
|
|
|
|
use List::Objects::WithUtils 'array'; |
681
|
|
|
|
|
|
|
|
682
|
|
|
|
|
|
|
my $array = array(qw/ a b c /); |
683
|
|
|
|
|
|
|
|
684
|
|
|
|
|
|
|
$array->push(qw/ d e f /); |
685
|
|
|
|
|
|
|
|
686
|
|
|
|
|
|
|
my @upper = $array->map(sub { uc })->all; |
687
|
|
|
|
|
|
|
|
688
|
|
|
|
|
|
|
if ( $array->has_any(sub { $_ eq 'a' }) ) { |
689
|
|
|
|
|
|
|
... |
690
|
|
|
|
|
|
|
} |
691
|
|
|
|
|
|
|
|
692
|
|
|
|
|
|
|
my $sum = array(1 .. 10)->reduce(sub { $a + $b }); |
693
|
|
|
|
|
|
|
|
694
|
|
|
|
|
|
|
# See below for full list of methods |
695
|
|
|
|
|
|
|
|
696
|
|
|
|
|
|
|
## As a Role -> |
697
|
|
|
|
|
|
|
use Role::Tiny::With; |
698
|
|
|
|
|
|
|
with 'List::Objects::WithUtils::Role::Array'; |
699
|
|
|
|
|
|
|
|
700
|
|
|
|
|
|
|
=head1 DESCRIPTION |
701
|
|
|
|
|
|
|
|
702
|
|
|
|
|
|
|
A L role defining methods for creating and manipulating ARRAY-type |
703
|
|
|
|
|
|
|
objects. |
704
|
|
|
|
|
|
|
|
705
|
|
|
|
|
|
|
L consumes this role (along with |
706
|
|
|
|
|
|
|
L) to provide B object |
707
|
|
|
|
|
|
|
methods. |
708
|
|
|
|
|
|
|
|
709
|
|
|
|
|
|
|
In addition to the methods documented below, these objects provide a |
710
|
|
|
|
|
|
|
C method exporting a plain ARRAY-type reference for convenience when |
711
|
|
|
|
|
|
|
feeding L or similar, as well as a C method for |
712
|
|
|
|
|
|
|
compatibility with L. |
713
|
|
|
|
|
|
|
|
714
|
|
|
|
|
|
|
=head2 Basic array methods |
715
|
|
|
|
|
|
|
|
716
|
|
|
|
|
|
|
=head3 new |
717
|
|
|
|
|
|
|
|
718
|
|
|
|
|
|
|
Constructs a new ARRAY-type object. |
719
|
|
|
|
|
|
|
|
720
|
|
|
|
|
|
|
=head3 copy |
721
|
|
|
|
|
|
|
|
722
|
|
|
|
|
|
|
Returns a shallow clone of the current object. |
723
|
|
|
|
|
|
|
|
724
|
|
|
|
|
|
|
=head3 count |
725
|
|
|
|
|
|
|
|
726
|
|
|
|
|
|
|
Returns the number of elements in the array. |
727
|
|
|
|
|
|
|
|
728
|
|
|
|
|
|
|
=head3 defined |
729
|
|
|
|
|
|
|
|
730
|
|
|
|
|
|
|
Returns true if the element at the specified position is defined. |
731
|
|
|
|
|
|
|
|
732
|
|
|
|
|
|
|
(Available from v2.13.1) |
733
|
|
|
|
|
|
|
|
734
|
|
|
|
|
|
|
=head3 end |
735
|
|
|
|
|
|
|
|
736
|
|
|
|
|
|
|
Returns the last index of the array (or -1 if the array is empty). |
737
|
|
|
|
|
|
|
|
738
|
|
|
|
|
|
|
=head3 exists |
739
|
|
|
|
|
|
|
|
740
|
|
|
|
|
|
|
Returns true if the specified index exists in the array. |
741
|
|
|
|
|
|
|
|
742
|
|
|
|
|
|
|
Negative indices work as you might expect: |
743
|
|
|
|
|
|
|
|
744
|
|
|
|
|
|
|
my $arr = array(1, 2, 3); |
745
|
|
|
|
|
|
|
$arr->set(-2 => 'foo') if $arr->exists(-2); |
746
|
|
|
|
|
|
|
# [ 1, 'foo', 3 ] |
747
|
|
|
|
|
|
|
|
748
|
|
|
|
|
|
|
(Available from v2.13.1) |
749
|
|
|
|
|
|
|
|
750
|
|
|
|
|
|
|
=head3 is_empty |
751
|
|
|
|
|
|
|
|
752
|
|
|
|
|
|
|
Returns boolean true if the array is empty. |
753
|
|
|
|
|
|
|
|
754
|
|
|
|
|
|
|
=head3 is_mutable |
755
|
|
|
|
|
|
|
|
756
|
|
|
|
|
|
|
Returns boolean true if the hash is mutable; immutable subclasses can override |
757
|
|
|
|
|
|
|
to provide a negative value. |
758
|
|
|
|
|
|
|
|
759
|
|
|
|
|
|
|
=head3 is_immutable |
760
|
|
|
|
|
|
|
|
761
|
|
|
|
|
|
|
The opposite of L. (Subclasses do not need to override so long as |
762
|
|
|
|
|
|
|
L returns a correct value.) |
763
|
|
|
|
|
|
|
|
764
|
|
|
|
|
|
|
=head3 inflate |
765
|
|
|
|
|
|
|
|
766
|
|
|
|
|
|
|
my $hash = $array->inflate; |
767
|
|
|
|
|
|
|
# Same as: |
768
|
|
|
|
|
|
|
# my $hash = hash( $array->all ) |
769
|
|
|
|
|
|
|
|
770
|
|
|
|
|
|
|
Inflates an array-type object to a hash-type object. |
771
|
|
|
|
|
|
|
|
772
|
|
|
|
|
|
|
Returns an object of type L; by default this is a |
773
|
|
|
|
|
|
|
L. |
774
|
|
|
|
|
|
|
|
775
|
|
|
|
|
|
|
Throws an exception if the array contains an odd number of elements. |
776
|
|
|
|
|
|
|
|
777
|
|
|
|
|
|
|
=head3 inflated_type |
778
|
|
|
|
|
|
|
|
779
|
|
|
|
|
|
|
The class name that objects are blessed into when calling L; |
780
|
|
|
|
|
|
|
subclasses can override to provide their own hash-type objects. |
781
|
|
|
|
|
|
|
|
782
|
|
|
|
|
|
|
Defaults to L. |
783
|
|
|
|
|
|
|
|
784
|
|
|
|
|
|
|
A consumer returning an C that is not a hash-type object will |
785
|
|
|
|
|
|
|
result in undefined behavior. |
786
|
|
|
|
|
|
|
|
787
|
|
|
|
|
|
|
=head3 scalar |
788
|
|
|
|
|
|
|
|
789
|
|
|
|
|
|
|
See L. |
790
|
|
|
|
|
|
|
|
791
|
|
|
|
|
|
|
=head3 unbless |
792
|
|
|
|
|
|
|
|
793
|
|
|
|
|
|
|
Returns a plain C reference (shallow clone). |
794
|
|
|
|
|
|
|
|
795
|
|
|
|
|
|
|
=head2 Methods that manipulate the list |
796
|
|
|
|
|
|
|
|
797
|
|
|
|
|
|
|
=head3 clear |
798
|
|
|
|
|
|
|
|
799
|
|
|
|
|
|
|
Delete all elements from the array. |
800
|
|
|
|
|
|
|
|
801
|
|
|
|
|
|
|
Returns the newly-emptied array object. |
802
|
|
|
|
|
|
|
|
803
|
|
|
|
|
|
|
=head3 delete |
804
|
|
|
|
|
|
|
|
805
|
|
|
|
|
|
|
Splices a given index out of the array. |
806
|
|
|
|
|
|
|
|
807
|
|
|
|
|
|
|
Returns the removed value. |
808
|
|
|
|
|
|
|
|
809
|
|
|
|
|
|
|
=head3 delete_when |
810
|
|
|
|
|
|
|
|
811
|
|
|
|
|
|
|
$array->delete_when( sub { $_ eq 'foo' } ); |
812
|
|
|
|
|
|
|
|
813
|
|
|
|
|
|
|
Splices all items out of the array for which the given subroutine evaluates to |
814
|
|
|
|
|
|
|
true. |
815
|
|
|
|
|
|
|
|
816
|
|
|
|
|
|
|
Returns a new array object containing the deleted values (possibly none). |
817
|
|
|
|
|
|
|
|
818
|
|
|
|
|
|
|
=head3 insert |
819
|
|
|
|
|
|
|
|
820
|
|
|
|
|
|
|
$array->insert( $position, $value ); |
821
|
|
|
|
|
|
|
$array->insert( $position, @values ); |
822
|
|
|
|
|
|
|
|
823
|
|
|
|
|
|
|
Inserts values at a given position, moving the rest of the array |
824
|
|
|
|
|
|
|
rightwards. |
825
|
|
|
|
|
|
|
|
826
|
|
|
|
|
|
|
The array will be "backfilled" (with undefs) if $position is past the end of |
827
|
|
|
|
|
|
|
the array. |
828
|
|
|
|
|
|
|
|
829
|
|
|
|
|
|
|
Returns the array object. |
830
|
|
|
|
|
|
|
|
831
|
|
|
|
|
|
|
(Available from v2.12.1) |
832
|
|
|
|
|
|
|
|
833
|
|
|
|
|
|
|
=head3 pop |
834
|
|
|
|
|
|
|
|
835
|
|
|
|
|
|
|
Pops the last element off the array and returns it. |
836
|
|
|
|
|
|
|
|
837
|
|
|
|
|
|
|
=head3 push |
838
|
|
|
|
|
|
|
|
839
|
|
|
|
|
|
|
Pushes elements to the end of the array. |
840
|
|
|
|
|
|
|
|
841
|
|
|
|
|
|
|
Returns the array object. |
842
|
|
|
|
|
|
|
|
843
|
|
|
|
|
|
|
=head3 rotate_in_place |
844
|
|
|
|
|
|
|
|
845
|
|
|
|
|
|
|
array(1 .. 3)->rotate_in_place; # 2, 3, 1 |
846
|
|
|
|
|
|
|
array(1 .. 3)->rotate_in_place(right => 1); # 3, 1, 2 |
847
|
|
|
|
|
|
|
|
848
|
|
|
|
|
|
|
Rotates the array in-place. A direction can be given. |
849
|
|
|
|
|
|
|
|
850
|
|
|
|
|
|
|
Also see L, L. |
851
|
|
|
|
|
|
|
|
852
|
|
|
|
|
|
|
=head3 set |
853
|
|
|
|
|
|
|
|
854
|
|
|
|
|
|
|
$array->set( $index, $value ); |
855
|
|
|
|
|
|
|
|
856
|
|
|
|
|
|
|
Takes an array element and a new value to set. |
857
|
|
|
|
|
|
|
|
858
|
|
|
|
|
|
|
Returns the array object. |
859
|
|
|
|
|
|
|
|
860
|
|
|
|
|
|
|
=head3 shift |
861
|
|
|
|
|
|
|
|
862
|
|
|
|
|
|
|
Shifts the first element off the beginning of the array and returns it. |
863
|
|
|
|
|
|
|
|
864
|
|
|
|
|
|
|
=head3 unshift |
865
|
|
|
|
|
|
|
|
866
|
|
|
|
|
|
|
Adds elements to the beginning of the array. |
867
|
|
|
|
|
|
|
|
868
|
|
|
|
|
|
|
Returns the array object. |
869
|
|
|
|
|
|
|
|
870
|
|
|
|
|
|
|
=head3 splice |
871
|
|
|
|
|
|
|
|
872
|
|
|
|
|
|
|
# 1- or 2-arg splice (remove elements): |
873
|
|
|
|
|
|
|
my $spliced = $array->splice(0, 2) |
874
|
|
|
|
|
|
|
# 3-arg splice (replace): |
875
|
|
|
|
|
|
|
$array->splice(0, 1, 'abc'); |
876
|
|
|
|
|
|
|
|
877
|
|
|
|
|
|
|
Performs a C on the current list and returns a new array object |
878
|
|
|
|
|
|
|
consisting of the items returned from the splice. |
879
|
|
|
|
|
|
|
|
880
|
|
|
|
|
|
|
The existing array is modified in-place. |
881
|
|
|
|
|
|
|
|
882
|
|
|
|
|
|
|
=head3 validated |
883
|
|
|
|
|
|
|
|
884
|
|
|
|
|
|
|
use Types::Standard -all; |
885
|
|
|
|
|
|
|
my $valid = array(qw/foo bar baz/)->validated(Str); |
886
|
|
|
|
|
|
|
|
887
|
|
|
|
|
|
|
Accepts a L type, against which each element of the current array |
888
|
|
|
|
|
|
|
will be checked before being added to a new array. Returns the new array. |
889
|
|
|
|
|
|
|
|
890
|
|
|
|
|
|
|
If the element fails the type check but can be coerced, the coerced value will |
891
|
|
|
|
|
|
|
be added to the new array. |
892
|
|
|
|
|
|
|
|
893
|
|
|
|
|
|
|
Dies with a stack trace if the value fails type checks and can't be coerced. |
894
|
|
|
|
|
|
|
|
895
|
|
|
|
|
|
|
(You probably want an B object from |
896
|
|
|
|
|
|
|
L instead.) |
897
|
|
|
|
|
|
|
|
898
|
|
|
|
|
|
|
See: L, L |
899
|
|
|
|
|
|
|
|
900
|
|
|
|
|
|
|
=head2 Methods that retrieve items |
901
|
|
|
|
|
|
|
|
902
|
|
|
|
|
|
|
=head3 all |
903
|
|
|
|
|
|
|
|
904
|
|
|
|
|
|
|
Returns all elements in the array as a plain list. |
905
|
|
|
|
|
|
|
|
906
|
|
|
|
|
|
|
=head3 bisect |
907
|
|
|
|
|
|
|
|
908
|
|
|
|
|
|
|
my ($true, $false) = array( 1 .. 10 ) |
909
|
|
|
|
|
|
|
->bisect(sub { $_ >= 5 }) |
910
|
|
|
|
|
|
|
->all; |
911
|
|
|
|
|
|
|
my @bigger = $true->all; # ( 5 .. 10 ) |
912
|
|
|
|
|
|
|
my @smaller = $false->all; # ( 1 .. 4 ) |
913
|
|
|
|
|
|
|
|
914
|
|
|
|
|
|
|
Like L, but creates an array-type object containing two |
915
|
|
|
|
|
|
|
partitions; the first contains all items for which the subroutine evaluates to |
916
|
|
|
|
|
|
|
true, the second contains items for which the subroutine evaluates to false. |
917
|
|
|
|
|
|
|
|
918
|
|
|
|
|
|
|
=head3 nsect |
919
|
|
|
|
|
|
|
|
920
|
|
|
|
|
|
|
my ($first, $second) = array( 1 .. 10 )->nsect(2)->all; |
921
|
|
|
|
|
|
|
# array( 1 .. 5 ), array( 6 .. 10 ) |
922
|
|
|
|
|
|
|
|
923
|
|
|
|
|
|
|
Like L and L, but takes an (integer) number of sets to create. |
924
|
|
|
|
|
|
|
|
925
|
|
|
|
|
|
|
If there are no items in the list (or no sections are requested), |
926
|
|
|
|
|
|
|
an empty array-type object is returned. |
927
|
|
|
|
|
|
|
|
928
|
|
|
|
|
|
|
If the list divides unevenly, the first set will be the largest. |
929
|
|
|
|
|
|
|
|
930
|
|
|
|
|
|
|
Inspired by L. |
931
|
|
|
|
|
|
|
|
932
|
|
|
|
|
|
|
(Available from v2.11.1) |
933
|
|
|
|
|
|
|
|
934
|
|
|
|
|
|
|
=head3 ssect |
935
|
|
|
|
|
|
|
|
936
|
|
|
|
|
|
|
my ($first, $second) = array( 1 .. 10 )->ssect(5)->all; |
937
|
|
|
|
|
|
|
# array( 1 .. 5 ), array( 6 .. 10 ); |
938
|
|
|
|
|
|
|
|
939
|
|
|
|
|
|
|
Like L and L, but takes an (integer) target number of items |
940
|
|
|
|
|
|
|
per set. |
941
|
|
|
|
|
|
|
|
942
|
|
|
|
|
|
|
If the list divides unevenly, the last set will be smaller than the specified |
943
|
|
|
|
|
|
|
target. |
944
|
|
|
|
|
|
|
|
945
|
|
|
|
|
|
|
Inspired by L. |
946
|
|
|
|
|
|
|
|
947
|
|
|
|
|
|
|
(Available from v2.11.1) |
948
|
|
|
|
|
|
|
|
949
|
|
|
|
|
|
|
=head3 elements |
950
|
|
|
|
|
|
|
|
951
|
|
|
|
|
|
|
Same as L; included for consistency with similar array-type object |
952
|
|
|
|
|
|
|
classes. |
953
|
|
|
|
|
|
|
|
954
|
|
|
|
|
|
|
=head3 export |
955
|
|
|
|
|
|
|
|
956
|
|
|
|
|
|
|
Same as L; included for consistency with hash-type objects. |
957
|
|
|
|
|
|
|
|
958
|
|
|
|
|
|
|
=head3 flatten |
959
|
|
|
|
|
|
|
|
960
|
|
|
|
|
|
|
Flatten array objects to plain lists, possibly recursively. |
961
|
|
|
|
|
|
|
|
962
|
|
|
|
|
|
|
C without arguments is the same as L: |
963
|
|
|
|
|
|
|
|
964
|
|
|
|
|
|
|
my @flat = array( 1, 2, [ 3, 4 ] )->flatten; |
965
|
|
|
|
|
|
|
# @flat = ( 1, 2, [ 3, 4 ] ); |
966
|
|
|
|
|
|
|
|
967
|
|
|
|
|
|
|
If a depth is specified, sub-arrays are recursively flattened until the |
968
|
|
|
|
|
|
|
specified depth is reached: |
969
|
|
|
|
|
|
|
|
970
|
|
|
|
|
|
|
my @flat = array( 1, 2, [ 3, 4 ] )->flatten(1); |
971
|
|
|
|
|
|
|
# @flat = ( 1, 2, 3, 4 ); |
972
|
|
|
|
|
|
|
|
973
|
|
|
|
|
|
|
my @flat = array( 1, 2, [ 3, 4, [ 5, 6 ] ] )->flatten(1); |
974
|
|
|
|
|
|
|
# @flat = ( 1, 2, 3, 4, [ 5, 6 ] ); |
975
|
|
|
|
|
|
|
|
976
|
|
|
|
|
|
|
This works with both ARRAY-type references and array objects: |
977
|
|
|
|
|
|
|
|
978
|
|
|
|
|
|
|
my @flat = array( 1, 2, [ 3, 4, array( 5, 6 ) ] )->flatten(2); |
979
|
|
|
|
|
|
|
# @flat = ( 1, 2, 3, 4, 5, 6 ); |
980
|
|
|
|
|
|
|
|
981
|
|
|
|
|
|
|
(Specifically, consumers of this role and plain ARRAYs are flattened; other |
982
|
|
|
|
|
|
|
ARRAY-type objects are left alone.) |
983
|
|
|
|
|
|
|
|
984
|
|
|
|
|
|
|
See L for flattening to an unlimited depth. |
985
|
|
|
|
|
|
|
|
986
|
|
|
|
|
|
|
=head3 flatten_all |
987
|
|
|
|
|
|
|
|
988
|
|
|
|
|
|
|
Returns a plain list consisting of all sub-arrays recursively |
989
|
|
|
|
|
|
|
flattened. Also see L. |
990
|
|
|
|
|
|
|
|
991
|
|
|
|
|
|
|
=head3 get |
992
|
|
|
|
|
|
|
|
993
|
|
|
|
|
|
|
Returns the array element corresponding to a specified index. |
994
|
|
|
|
|
|
|
|
995
|
|
|
|
|
|
|
=head3 get_or_else |
996
|
|
|
|
|
|
|
|
997
|
|
|
|
|
|
|
# Expect to find an object at $pos in $array, |
998
|
|
|
|
|
|
|
# or return an empty one if $pos is undef: |
999
|
|
|
|
|
|
|
my @keys = $array->get_or_else($pos => hash)->keys->all; |
1000
|
|
|
|
|
|
|
|
1001
|
|
|
|
|
|
|
# Or pass a coderef that provides a default return value; |
1002
|
|
|
|
|
|
|
# First arg is the object being operated on: |
1003
|
|
|
|
|
|
|
my $item_or_first = $array->get_or_else($pos => sub { shift->get(0) }); |
1004
|
|
|
|
|
|
|
# Second arg is the requested index: |
1005
|
|
|
|
|
|
|
my $item = $array->get_or_else(3 => sub { |
1006
|
|
|
|
|
|
|
my (undef, $pos) = @_; |
1007
|
|
|
|
|
|
|
my $created = make_value_for( $pos ); |
1008
|
|
|
|
|
|
|
$array->set($pos => $created); |
1009
|
|
|
|
|
|
|
$created |
1010
|
|
|
|
|
|
|
}); |
1011
|
|
|
|
|
|
|
|
1012
|
|
|
|
|
|
|
Returns the element corresponding to a specified index; optionally takes a |
1013
|
|
|
|
|
|
|
second argument that is used as a default return value if the given index is |
1014
|
|
|
|
|
|
|
undef (the array remains unmodified). |
1015
|
|
|
|
|
|
|
|
1016
|
|
|
|
|
|
|
If the second argument is a coderef, it is invoked on the object (with the |
1017
|
|
|
|
|
|
|
requested index as an argument) and its return value is taken as the default. |
1018
|
|
|
|
|
|
|
|
1019
|
|
|
|
|
|
|
=head3 head |
1020
|
|
|
|
|
|
|
|
1021
|
|
|
|
|
|
|
my ($first, $rest) = $array->head; |
1022
|
|
|
|
|
|
|
|
1023
|
|
|
|
|
|
|
In list context, returns the first element of the list, and a new array-type |
1024
|
|
|
|
|
|
|
object containing the remaining list. The original object's list is untouched. |
1025
|
|
|
|
|
|
|
|
1026
|
|
|
|
|
|
|
In scalar context, returns just the first element of the array: |
1027
|
|
|
|
|
|
|
|
1028
|
|
|
|
|
|
|
my $first = $array->head; |
1029
|
|
|
|
|
|
|
|
1030
|
|
|
|
|
|
|
=head3 tail |
1031
|
|
|
|
|
|
|
|
1032
|
|
|
|
|
|
|
Similar to L, but returns either the last element and a new array-type |
1033
|
|
|
|
|
|
|
object containing the remaining list (in list context), or just the last |
1034
|
|
|
|
|
|
|
element of the list (in scalar context). |
1035
|
|
|
|
|
|
|
|
1036
|
|
|
|
|
|
|
=head3 join |
1037
|
|
|
|
|
|
|
|
1038
|
|
|
|
|
|
|
my $str = $array->join(' '); |
1039
|
|
|
|
|
|
|
|
1040
|
|
|
|
|
|
|
Joins the array's elements and returns the joined string. |
1041
|
|
|
|
|
|
|
|
1042
|
|
|
|
|
|
|
Defaults to ',' if no delimiter is specified. |
1043
|
|
|
|
|
|
|
|
1044
|
|
|
|
|
|
|
=head3 kv |
1045
|
|
|
|
|
|
|
|
1046
|
|
|
|
|
|
|
Returns an array-type object containing index/value pairs as (unblessed) ARRAYs; |
1047
|
|
|
|
|
|
|
this is much like L, except the |
1048
|
|
|
|
|
|
|
array index is the "key." |
1049
|
|
|
|
|
|
|
|
1050
|
|
|
|
|
|
|
=head3 zip |
1051
|
|
|
|
|
|
|
|
1052
|
|
|
|
|
|
|
=head3 mesh |
1053
|
|
|
|
|
|
|
|
1054
|
|
|
|
|
|
|
my $meshed = array(qw/ a b c /)->mesh( |
1055
|
|
|
|
|
|
|
array( 1 .. 3 ) |
1056
|
|
|
|
|
|
|
); |
1057
|
|
|
|
|
|
|
$meshed->all; # 'a', 1, 'b', 2, 'c', 3 |
1058
|
|
|
|
|
|
|
|
1059
|
|
|
|
|
|
|
Takes array references or objects and returns a new array object consisting of |
1060
|
|
|
|
|
|
|
one element from each array, in turn, until all arrays have been traversed |
1061
|
|
|
|
|
|
|
fully. |
1062
|
|
|
|
|
|
|
|
1063
|
|
|
|
|
|
|
You can mix and match references and objects freely: |
1064
|
|
|
|
|
|
|
|
1065
|
|
|
|
|
|
|
my $meshed = array(qw/ a b c /)->mesh( |
1066
|
|
|
|
|
|
|
array( 1 .. 3 ), |
1067
|
|
|
|
|
|
|
[ qw/ foo bar baz / ], |
1068
|
|
|
|
|
|
|
); |
1069
|
|
|
|
|
|
|
|
1070
|
|
|
|
|
|
|
(C is an alias for C.) |
1071
|
|
|
|
|
|
|
|
1072
|
|
|
|
|
|
|
=head3 part |
1073
|
|
|
|
|
|
|
|
1074
|
|
|
|
|
|
|
my $parts = array( 1 .. 8 )->part(sub { $i++ % 2 }); |
1075
|
|
|
|
|
|
|
# Returns array objects: |
1076
|
|
|
|
|
|
|
$parts->get(0)->all; # 1, 3, 5, 7 |
1077
|
|
|
|
|
|
|
$parts->get(1)->all; # 2, 4, 6, 8 |
1078
|
|
|
|
|
|
|
|
1079
|
|
|
|
|
|
|
Takes a subroutine that indicates into which partition each value should be |
1080
|
|
|
|
|
|
|
placed. |
1081
|
|
|
|
|
|
|
|
1082
|
|
|
|
|
|
|
Returns an array-type object containing partitions represented as array-type |
1083
|
|
|
|
|
|
|
objects, as seen above. |
1084
|
|
|
|
|
|
|
|
1085
|
|
|
|
|
|
|
Skipped partitions are empty array objects: |
1086
|
|
|
|
|
|
|
|
1087
|
|
|
|
|
|
|
my $parts = array(qw/ foo bar /)->part(sub { 1 }); |
1088
|
|
|
|
|
|
|
$parts->get(0)->is_empty; # true |
1089
|
|
|
|
|
|
|
$parts->get(1)->is_empty; # false |
1090
|
|
|
|
|
|
|
|
1091
|
|
|
|
|
|
|
The subroutine is passed the value we are operating on, or you can use the |
1092
|
|
|
|
|
|
|
topicalizer C<$_>: |
1093
|
|
|
|
|
|
|
|
1094
|
|
|
|
|
|
|
array(qw/foo bar baz 1 2 3/) |
1095
|
|
|
|
|
|
|
->part(sub { m/^[0-9]+$/ ? 0 : 1 }) |
1096
|
|
|
|
|
|
|
->get(1) |
1097
|
|
|
|
|
|
|
->all; # 'foo', 'bar', 'baz' |
1098
|
|
|
|
|
|
|
|
1099
|
|
|
|
|
|
|
=head3 part_to_hash |
1100
|
|
|
|
|
|
|
|
1101
|
|
|
|
|
|
|
my $people = array(qw/ann andy bob fred frankie/); |
1102
|
|
|
|
|
|
|
my $parts = $people->part_to_hash(sub { ucfirst substr $_, 0, 1 }); |
1103
|
|
|
|
|
|
|
$parts->get('A')->all; # 'ann', 'andy' |
1104
|
|
|
|
|
|
|
|
1105
|
|
|
|
|
|
|
Like L, but partitions values into a hash-type object using the result |
1106
|
|
|
|
|
|
|
of the given subroutine as the hash key; the values are array-type objects. |
1107
|
|
|
|
|
|
|
|
1108
|
|
|
|
|
|
|
The returned object is of type L; by default this is a |
1109
|
|
|
|
|
|
|
L. |
1110
|
|
|
|
|
|
|
|
1111
|
|
|
|
|
|
|
(Available from v2.23.1) |
1112
|
|
|
|
|
|
|
|
1113
|
|
|
|
|
|
|
=head3 pick |
1114
|
|
|
|
|
|
|
|
1115
|
|
|
|
|
|
|
my $picked = array('a' .. 'f')->pick(3); |
1116
|
|
|
|
|
|
|
|
1117
|
|
|
|
|
|
|
Returns a new array object containing the specified number of elements chosen |
1118
|
|
|
|
|
|
|
randomly and without repetition. |
1119
|
|
|
|
|
|
|
|
1120
|
|
|
|
|
|
|
If the given number is equal to or greater than the number of elements in the |
1121
|
|
|
|
|
|
|
list, C will return a shuffled list (same as calling L). |
1122
|
|
|
|
|
|
|
|
1123
|
|
|
|
|
|
|
(Available from v2.26.1) |
1124
|
|
|
|
|
|
|
|
1125
|
|
|
|
|
|
|
=head3 random |
1126
|
|
|
|
|
|
|
|
1127
|
|
|
|
|
|
|
Returns a random element from the array. |
1128
|
|
|
|
|
|
|
|
1129
|
|
|
|
|
|
|
=head3 reverse |
1130
|
|
|
|
|
|
|
|
1131
|
|
|
|
|
|
|
Returns a new array object consisting of the reversed list of elements. |
1132
|
|
|
|
|
|
|
|
1133
|
|
|
|
|
|
|
=head3 roll |
1134
|
|
|
|
|
|
|
|
1135
|
|
|
|
|
|
|
Much like L, but repeated entries in the resultant list are allowed, |
1136
|
|
|
|
|
|
|
and the number of entries to return may be larger than the size of the array. |
1137
|
|
|
|
|
|
|
|
1138
|
|
|
|
|
|
|
If the number of elements to return is not specified, the size of the original |
1139
|
|
|
|
|
|
|
array is used. |
1140
|
|
|
|
|
|
|
|
1141
|
|
|
|
|
|
|
(Available from v2.26.1) |
1142
|
|
|
|
|
|
|
|
1143
|
|
|
|
|
|
|
=head3 rotate |
1144
|
|
|
|
|
|
|
|
1145
|
|
|
|
|
|
|
my $leftwards = $array->rotate; |
1146
|
|
|
|
|
|
|
my $rightwards = $array->rotate(right => 1); |
1147
|
|
|
|
|
|
|
|
1148
|
|
|
|
|
|
|
Returns a new array object containing the rotated list. |
1149
|
|
|
|
|
|
|
|
1150
|
|
|
|
|
|
|
Also see L, L. |
1151
|
|
|
|
|
|
|
|
1152
|
|
|
|
|
|
|
=head3 shuffle |
1153
|
|
|
|
|
|
|
|
1154
|
|
|
|
|
|
|
my $shuffled = $array->shuffle; |
1155
|
|
|
|
|
|
|
|
1156
|
|
|
|
|
|
|
Returns a new array object containing the shuffled list. |
1157
|
|
|
|
|
|
|
|
1158
|
|
|
|
|
|
|
=head3 sliced |
1159
|
|
|
|
|
|
|
|
1160
|
|
|
|
|
|
|
my $slice = $array->sliced(1, 3, 5); |
1161
|
|
|
|
|
|
|
|
1162
|
|
|
|
|
|
|
Returns a new array object consisting of the elements retrived |
1163
|
|
|
|
|
|
|
from the specified indexes. |
1164
|
|
|
|
|
|
|
|
1165
|
|
|
|
|
|
|
=head3 tuples |
1166
|
|
|
|
|
|
|
|
1167
|
|
|
|
|
|
|
my $tuples = array(1 .. 7)->tuples(2); |
1168
|
|
|
|
|
|
|
# Returns: |
1169
|
|
|
|
|
|
|
# array( |
1170
|
|
|
|
|
|
|
# [ 1, 2 ], |
1171
|
|
|
|
|
|
|
# [ 3, 4 ], |
1172
|
|
|
|
|
|
|
# [ 5, 6 ], |
1173
|
|
|
|
|
|
|
# [ 7 ], |
1174
|
|
|
|
|
|
|
# ) |
1175
|
|
|
|
|
|
|
|
1176
|
|
|
|
|
|
|
Returns a new array object consisting of tuples (unblessed ARRAY references) |
1177
|
|
|
|
|
|
|
of the specified size (defaults to 2). |
1178
|
|
|
|
|
|
|
|
1179
|
|
|
|
|
|
|
C accepts L types as an optional second parameter; if |
1180
|
|
|
|
|
|
|
specified, items in tuples are checked against the type and a coercion is |
1181
|
|
|
|
|
|
|
attempted (if available for the given type) if the initial type-check fails: |
1182
|
|
|
|
|
|
|
|
1183
|
|
|
|
|
|
|
use Types::Standard -all; |
1184
|
|
|
|
|
|
|
my $tuples = array(1 .. 7)->tuples(2 => Int); |
1185
|
|
|
|
|
|
|
|
1186
|
|
|
|
|
|
|
A stack-trace is thrown if a value in a tuple cannot be made to validate. |
1187
|
|
|
|
|
|
|
|
1188
|
|
|
|
|
|
|
As of v2.24.1, it's possible to make the returned tuples blessed array-type |
1189
|
|
|
|
|
|
|
objects (of the type of the original class) by passing a boolean true third |
1190
|
|
|
|
|
|
|
parameter: |
1191
|
|
|
|
|
|
|
|
1192
|
|
|
|
|
|
|
# bless()'d tuples, no type validation or coercion: |
1193
|
|
|
|
|
|
|
my $tuples = array(1 .. 7)->tuples(2, undef, 'bless'); |
1194
|
|
|
|
|
|
|
|
1195
|
|
|
|
|
|
|
See: L, L |
1196
|
|
|
|
|
|
|
|
1197
|
|
|
|
|
|
|
=head2 Methods that find items |
1198
|
|
|
|
|
|
|
|
1199
|
|
|
|
|
|
|
=head3 grep |
1200
|
|
|
|
|
|
|
|
1201
|
|
|
|
|
|
|
my $matched = $array->grep(sub { /foo/ }); |
1202
|
|
|
|
|
|
|
|
1203
|
|
|
|
|
|
|
Returns a new array object consisting of the list of elements for which the |
1204
|
|
|
|
|
|
|
given subroutine evaluates to true. C<$_[0]> is the element being operated |
1205
|
|
|
|
|
|
|
on; you can also use the topicalizer C<$_>. |
1206
|
|
|
|
|
|
|
|
1207
|
|
|
|
|
|
|
=head3 indexes |
1208
|
|
|
|
|
|
|
|
1209
|
|
|
|
|
|
|
my $matched = $array->indexes(sub { /foo/ }); |
1210
|
|
|
|
|
|
|
|
1211
|
|
|
|
|
|
|
If passed a reference to a subroutine, C behaves like L, but |
1212
|
|
|
|
|
|
|
returns a new array object consisting of the list of array indexes for which |
1213
|
|
|
|
|
|
|
the given subroutine evaluates to true. |
1214
|
|
|
|
|
|
|
|
1215
|
|
|
|
|
|
|
If no subroutine is provided, returns a new array object consisting of the |
1216
|
|
|
|
|
|
|
full list of indexes (like C on an array in perl-5.12+). This feature |
1217
|
|
|
|
|
|
|
was added in C. |
1218
|
|
|
|
|
|
|
|
1219
|
|
|
|
|
|
|
=head3 first_where |
1220
|
|
|
|
|
|
|
|
1221
|
|
|
|
|
|
|
my $arr = array( qw/ ab bc bd de / ); |
1222
|
|
|
|
|
|
|
my $first = $arr->first_where(sub { /^b/ }); ## 'bc' |
1223
|
|
|
|
|
|
|
|
1224
|
|
|
|
|
|
|
Returns the first element of the list for which the given sub evaluates to |
1225
|
|
|
|
|
|
|
true. C<$_> is set to each element, in turn, until a match is found (or we run |
1226
|
|
|
|
|
|
|
out of possibles). |
1227
|
|
|
|
|
|
|
|
1228
|
|
|
|
|
|
|
=head3 first_index |
1229
|
|
|
|
|
|
|
|
1230
|
|
|
|
|
|
|
Like L, but return the index of the first successful match. |
1231
|
|
|
|
|
|
|
|
1232
|
|
|
|
|
|
|
Returns -1 if no match is found. |
1233
|
|
|
|
|
|
|
|
1234
|
|
|
|
|
|
|
=head3 firstidx |
1235
|
|
|
|
|
|
|
|
1236
|
|
|
|
|
|
|
An alias for L. |
1237
|
|
|
|
|
|
|
|
1238
|
|
|
|
|
|
|
=head3 last_where |
1239
|
|
|
|
|
|
|
|
1240
|
|
|
|
|
|
|
Like L, but returns the B successful match. |
1241
|
|
|
|
|
|
|
|
1242
|
|
|
|
|
|
|
=head3 last_index |
1243
|
|
|
|
|
|
|
|
1244
|
|
|
|
|
|
|
Like L, but returns the index of the B successful match. |
1245
|
|
|
|
|
|
|
|
1246
|
|
|
|
|
|
|
=head3 lastidx |
1247
|
|
|
|
|
|
|
|
1248
|
|
|
|
|
|
|
An alias for L. |
1249
|
|
|
|
|
|
|
|
1250
|
|
|
|
|
|
|
=head3 has_any |
1251
|
|
|
|
|
|
|
|
1252
|
|
|
|
|
|
|
if ( $array->has_any(sub { $_ eq 'foo' }) ) { |
1253
|
|
|
|
|
|
|
... |
1254
|
|
|
|
|
|
|
} |
1255
|
|
|
|
|
|
|
|
1256
|
|
|
|
|
|
|
If passed no arguments, returns boolean true if the array has any elements. |
1257
|
|
|
|
|
|
|
|
1258
|
|
|
|
|
|
|
If passed a sub, returns boolean true if the sub is true for any element |
1259
|
|
|
|
|
|
|
of the array. |
1260
|
|
|
|
|
|
|
|
1261
|
|
|
|
|
|
|
C<$_> is set to the element being operated upon. |
1262
|
|
|
|
|
|
|
|
1263
|
|
|
|
|
|
|
=head3 intersection |
1264
|
|
|
|
|
|
|
|
1265
|
|
|
|
|
|
|
my $first = array(qw/ a b c /); |
1266
|
|
|
|
|
|
|
my $second = array(qw/ b c d /); |
1267
|
|
|
|
|
|
|
my $intersection = $first->intersection($second); |
1268
|
|
|
|
|
|
|
|
1269
|
|
|
|
|
|
|
Returns a new array object containing the list of values common between all |
1270
|
|
|
|
|
|
|
given array-type objects (including the invocant). |
1271
|
|
|
|
|
|
|
|
1272
|
|
|
|
|
|
|
The new array object is not sorted in any predictable order. |
1273
|
|
|
|
|
|
|
|
1274
|
|
|
|
|
|
|
(It may be worth noting that an intermediate hash is used; objects that |
1275
|
|
|
|
|
|
|
stringify to the same value will be taken to be the same.) |
1276
|
|
|
|
|
|
|
|
1277
|
|
|
|
|
|
|
=head3 diff |
1278
|
|
|
|
|
|
|
|
1279
|
|
|
|
|
|
|
my $first = array(qw/ a b c d /); |
1280
|
|
|
|
|
|
|
my $second = array(qw/ b c x /); |
1281
|
|
|
|
|
|
|
my @diff = $first->diff($second)->sort->all; # (a, d, x) |
1282
|
|
|
|
|
|
|
|
1283
|
|
|
|
|
|
|
The opposite of L; returns a new array object containing the |
1284
|
|
|
|
|
|
|
list of values that are not common between all given array-type objects |
1285
|
|
|
|
|
|
|
(including the invocant). |
1286
|
|
|
|
|
|
|
|
1287
|
|
|
|
|
|
|
The same constraints as L apply. |
1288
|
|
|
|
|
|
|
|
1289
|
|
|
|
|
|
|
=head3 items_after |
1290
|
|
|
|
|
|
|
|
1291
|
|
|
|
|
|
|
my $after = array( 1 .. 10 )->items_after(sub { $_ == 5 }); |
1292
|
|
|
|
|
|
|
## $after contains [ 6, 7, 8, 9, 10 ] |
1293
|
|
|
|
|
|
|
|
1294
|
|
|
|
|
|
|
Returns a new array object consisting of the elements of the original list |
1295
|
|
|
|
|
|
|
that occur after the first position for which the given sub evaluates to true. |
1296
|
|
|
|
|
|
|
|
1297
|
|
|
|
|
|
|
=head3 items_after_incl |
1298
|
|
|
|
|
|
|
|
1299
|
|
|
|
|
|
|
Like L, but include the item that evaluated to true. |
1300
|
|
|
|
|
|
|
|
1301
|
|
|
|
|
|
|
=head3 items_before |
1302
|
|
|
|
|
|
|
|
1303
|
|
|
|
|
|
|
The opposite of L. |
1304
|
|
|
|
|
|
|
|
1305
|
|
|
|
|
|
|
=head3 items_before_incl |
1306
|
|
|
|
|
|
|
|
1307
|
|
|
|
|
|
|
The opposite of L. |
1308
|
|
|
|
|
|
|
|
1309
|
|
|
|
|
|
|
=head2 Methods that iterate the list |
1310
|
|
|
|
|
|
|
|
1311
|
|
|
|
|
|
|
=head3 map |
1312
|
|
|
|
|
|
|
|
1313
|
|
|
|
|
|
|
my $lowercased = $array->map(sub { lc }); |
1314
|
|
|
|
|
|
|
# Same as: |
1315
|
|
|
|
|
|
|
my $lowercased = $array->map(sub { lc $_[0] }); |
1316
|
|
|
|
|
|
|
|
1317
|
|
|
|
|
|
|
Evaluates a given subroutine for each element of the array, and returns a new |
1318
|
|
|
|
|
|
|
array object. C<$_[0]> is the element being operated on; you can also use |
1319
|
|
|
|
|
|
|
the topicalizer C<$_>. |
1320
|
|
|
|
|
|
|
|
1321
|
|
|
|
|
|
|
Also see L. |
1322
|
|
|
|
|
|
|
|
1323
|
|
|
|
|
|
|
=head3 mapval |
1324
|
|
|
|
|
|
|
|
1325
|
|
|
|
|
|
|
my $orig = array(1, 2, 3); |
1326
|
|
|
|
|
|
|
my $incr = $orig->mapval(sub { ++$_ }); |
1327
|
|
|
|
|
|
|
|
1328
|
|
|
|
|
|
|
$incr->all; # (2, 3, 4) |
1329
|
|
|
|
|
|
|
$orig->all; # Still untouched |
1330
|
|
|
|
|
|
|
|
1331
|
|
|
|
|
|
|
An alternative to L. C<$_> is a copy, rather than an alias to the |
1332
|
|
|
|
|
|
|
current element, and the result is retrieved from the altered C<$_> rather |
1333
|
|
|
|
|
|
|
than the return value of the block. |
1334
|
|
|
|
|
|
|
|
1335
|
|
|
|
|
|
|
This feature is borrowed from L by Lukas Mai (CPAN: MAUKE). |
1336
|
|
|
|
|
|
|
|
1337
|
|
|
|
|
|
|
=head3 natatime |
1338
|
|
|
|
|
|
|
|
1339
|
|
|
|
|
|
|
my $iter = array( 1 .. 7 )->natatime(3); |
1340
|
|
|
|
|
|
|
$iter->(); ## ( 1, 2, 3 ) |
1341
|
|
|
|
|
|
|
$iter->(); ## ( 4, 5, 6 ) |
1342
|
|
|
|
|
|
|
$iter->(); ## ( 7 ) |
1343
|
|
|
|
|
|
|
|
1344
|
|
|
|
|
|
|
array( 1 .. 7 )->natatime(3, sub { my @vals = @_; ... }); |
1345
|
|
|
|
|
|
|
|
1346
|
|
|
|
|
|
|
Returns an iterator that, when called, produces a list containing the next |
1347
|
|
|
|
|
|
|
'n' items. |
1348
|
|
|
|
|
|
|
|
1349
|
|
|
|
|
|
|
If given a coderef as a second argument, it will be called against each |
1350
|
|
|
|
|
|
|
bundled group. |
1351
|
|
|
|
|
|
|
|
1352
|
|
|
|
|
|
|
=head3 rotator |
1353
|
|
|
|
|
|
|
|
1354
|
|
|
|
|
|
|
my $rot = array(qw/cat sheep mouse/); |
1355
|
|
|
|
|
|
|
$rot->(); ## 'cat' |
1356
|
|
|
|
|
|
|
$rot->(); ## 'sheep' |
1357
|
|
|
|
|
|
|
$rot->(); ## 'mouse' |
1358
|
|
|
|
|
|
|
$rot->(); ## 'cat' |
1359
|
|
|
|
|
|
|
|
1360
|
|
|
|
|
|
|
Returns an iterator that, when called, produces the next element in the array; |
1361
|
|
|
|
|
|
|
when there are no elements left, the iterator returns to the start of the |
1362
|
|
|
|
|
|
|
array. |
1363
|
|
|
|
|
|
|
|
1364
|
|
|
|
|
|
|
See also L, L. |
1365
|
|
|
|
|
|
|
|
1366
|
|
|
|
|
|
|
(Available from v2.7.1) |
1367
|
|
|
|
|
|
|
|
1368
|
|
|
|
|
|
|
=head3 reduce |
1369
|
|
|
|
|
|
|
|
1370
|
|
|
|
|
|
|
my $sum = array(1,2,3)->reduce(sub { $a + $b }); |
1371
|
|
|
|
|
|
|
|
1372
|
|
|
|
|
|
|
Reduces the array by calling the given subroutine for each element of the |
1373
|
|
|
|
|
|
|
list. C<$a> is the accumulated value; C<$b> is the current element. See |
1374
|
|
|
|
|
|
|
L. |
1375
|
|
|
|
|
|
|
|
1376
|
|
|
|
|
|
|
Prior to C, C<$_[0]> and C<$_[1]> must be used in place of C<$a> and |
1377
|
|
|
|
|
|
|
C<$b>, respectively. Using positional arguments may make for cleaner syntax in |
1378
|
|
|
|
|
|
|
some cases: |
1379
|
|
|
|
|
|
|
|
1380
|
|
|
|
|
|
|
my $divide = sub { |
1381
|
|
|
|
|
|
|
my ($acc, $next) = @_; |
1382
|
|
|
|
|
|
|
$acc / $next |
1383
|
|
|
|
|
|
|
}; |
1384
|
|
|
|
|
|
|
my $q = $array->reduce($divide); |
1385
|
|
|
|
|
|
|
|
1386
|
|
|
|
|
|
|
An empty list reduces to C. |
1387
|
|
|
|
|
|
|
|
1388
|
|
|
|
|
|
|
This is a "left fold" -- B is an alias for L (as of v2.17.1). |
1389
|
|
|
|
|
|
|
|
1390
|
|
|
|
|
|
|
See also: L |
1391
|
|
|
|
|
|
|
|
1392
|
|
|
|
|
|
|
=head3 foldr |
1393
|
|
|
|
|
|
|
|
1394
|
|
|
|
|
|
|
my $result = array(2,3,6)->foldr(sub { $_[1] / $_[0] }); # 1 |
1395
|
|
|
|
|
|
|
|
1396
|
|
|
|
|
|
|
Reduces the array by calling the given subroutine for each element of the |
1397
|
|
|
|
|
|
|
list starting at the end (the opposite of L). |
1398
|
|
|
|
|
|
|
|
1399
|
|
|
|
|
|
|
Unlike L (foldl), the first argument passed to the subroutine is the |
1400
|
|
|
|
|
|
|
current element; the second argument is the accumulated value. |
1401
|
|
|
|
|
|
|
|
1402
|
|
|
|
|
|
|
An empty list reduces to C. |
1403
|
|
|
|
|
|
|
|
1404
|
|
|
|
|
|
|
(Available from v2.17.1) |
1405
|
|
|
|
|
|
|
|
1406
|
|
|
|
|
|
|
=head3 visit |
1407
|
|
|
|
|
|
|
|
1408
|
|
|
|
|
|
|
$arr->visit(sub { warn "array contains: $_" }); |
1409
|
|
|
|
|
|
|
|
1410
|
|
|
|
|
|
|
Executes the given subroutine against each element sequentially; in practice |
1411
|
|
|
|
|
|
|
this is much like L, except the return value is thrown away. |
1412
|
|
|
|
|
|
|
|
1413
|
|
|
|
|
|
|
Returns the original array object. |
1414
|
|
|
|
|
|
|
|
1415
|
|
|
|
|
|
|
(Available from v2.7.1) |
1416
|
|
|
|
|
|
|
|
1417
|
|
|
|
|
|
|
=head2 Methods that sort the list |
1418
|
|
|
|
|
|
|
|
1419
|
|
|
|
|
|
|
=head3 sort |
1420
|
|
|
|
|
|
|
|
1421
|
|
|
|
|
|
|
my $sorted = $array->sort(sub { $a cmp $b }); |
1422
|
|
|
|
|
|
|
|
1423
|
|
|
|
|
|
|
Returns a new array object consisting of the list sorted by the given |
1424
|
|
|
|
|
|
|
subroutine. |
1425
|
|
|
|
|
|
|
|
1426
|
|
|
|
|
|
|
Prior to version 2.18.1, positional arguments (C<$_[0]> and C<$_[1]>) must be |
1427
|
|
|
|
|
|
|
used in place of C<$a> and C<$b>, respectively. |
1428
|
|
|
|
|
|
|
|
1429
|
|
|
|
|
|
|
=head3 sort_by |
1430
|
|
|
|
|
|
|
|
1431
|
|
|
|
|
|
|
my $array = array( |
1432
|
|
|
|
|
|
|
{ id => 'a' }, |
1433
|
|
|
|
|
|
|
{ id => 'c' }, |
1434
|
|
|
|
|
|
|
{ id => 'b' }, |
1435
|
|
|
|
|
|
|
); |
1436
|
|
|
|
|
|
|
my $sorted = $array->sort_by(sub { $_->{id} }); |
1437
|
|
|
|
|
|
|
|
1438
|
|
|
|
|
|
|
Returns a new array object consisting of the list of elements sorted via a |
1439
|
|
|
|
|
|
|
stringy comparison using the given sub. |
1440
|
|
|
|
|
|
|
See L. |
1441
|
|
|
|
|
|
|
|
1442
|
|
|
|
|
|
|
Uses L if available. |
1443
|
|
|
|
|
|
|
|
1444
|
|
|
|
|
|
|
=head3 nsort_by |
1445
|
|
|
|
|
|
|
|
1446
|
|
|
|
|
|
|
Like L, but using numerical comparison. |
1447
|
|
|
|
|
|
|
|
1448
|
|
|
|
|
|
|
=head3 repeated |
1449
|
|
|
|
|
|
|
|
1450
|
|
|
|
|
|
|
my $repeats = $array->repeated; |
1451
|
|
|
|
|
|
|
|
1452
|
|
|
|
|
|
|
The opposite of L; returns a new array object containing only repeated |
1453
|
|
|
|
|
|
|
elements. |
1454
|
|
|
|
|
|
|
|
1455
|
|
|
|
|
|
|
(The same constraints apply with regards to stringification; see L) |
1456
|
|
|
|
|
|
|
|
1457
|
|
|
|
|
|
|
(Available from v2.26.1) |
1458
|
|
|
|
|
|
|
|
1459
|
|
|
|
|
|
|
=head3 squished |
1460
|
|
|
|
|
|
|
|
1461
|
|
|
|
|
|
|
my $squished = array(qw/a a b a b b/)->squished; |
1462
|
|
|
|
|
|
|
# $squished = array( 'a', 'b', 'a', 'b' ); |
1463
|
|
|
|
|
|
|
|
1464
|
|
|
|
|
|
|
Similar to L, but only consecutively repeated values are removed from |
1465
|
|
|
|
|
|
|
the returned (new) array object. |
1466
|
|
|
|
|
|
|
|
1467
|
|
|
|
|
|
|
The same constraints as L apply with regards to stringification, but |
1468
|
|
|
|
|
|
|
multiple Cs in a row will also be squished. |
1469
|
|
|
|
|
|
|
|
1470
|
|
|
|
|
|
|
(Available from v2.27.1) |
1471
|
|
|
|
|
|
|
|
1472
|
|
|
|
|
|
|
=head3 uniq |
1473
|
|
|
|
|
|
|
|
1474
|
|
|
|
|
|
|
my $unique = $array->uniq; |
1475
|
|
|
|
|
|
|
|
1476
|
|
|
|
|
|
|
Returns a new array object containing only unique elements from the original |
1477
|
|
|
|
|
|
|
array. |
1478
|
|
|
|
|
|
|
|
1479
|
|
|
|
|
|
|
(It may be worth noting that this takes place via an intermediate hash; |
1480
|
|
|
|
|
|
|
objects that stringify to the same value are not unique, even if they are |
1481
|
|
|
|
|
|
|
different objects. L plus L may help you |
1482
|
|
|
|
|
|
|
there.) |
1483
|
|
|
|
|
|
|
|
1484
|
|
|
|
|
|
|
=head3 uniq_by |
1485
|
|
|
|
|
|
|
|
1486
|
|
|
|
|
|
|
my $array = array( |
1487
|
|
|
|
|
|
|
{ id => 'a' }, |
1488
|
|
|
|
|
|
|
{ id => 'a' }, |
1489
|
|
|
|
|
|
|
{ id => 'b' }, |
1490
|
|
|
|
|
|
|
); |
1491
|
|
|
|
|
|
|
my $unique = $array->uniq_by(sub { $_->{id} }); |
1492
|
|
|
|
|
|
|
|
1493
|
|
|
|
|
|
|
Returns a new array object consisting of the list of elements for which the |
1494
|
|
|
|
|
|
|
given sub returns unique values. |
1495
|
|
|
|
|
|
|
|
1496
|
|
|
|
|
|
|
Uses L if available; falls back to L if not. |
1497
|
|
|
|
|
|
|
|
1498
|
|
|
|
|
|
|
=head1 NOTES FOR CONSUMERS |
1499
|
|
|
|
|
|
|
|
1500
|
|
|
|
|
|
|
If creating your own consumer of this role, some extra effort is required to |
1501
|
|
|
|
|
|
|
make C<$a> and C<$b> work in sort statements without warnings; an example with |
1502
|
|
|
|
|
|
|
a custom exported constructor (and junction support) might look something like: |
1503
|
|
|
|
|
|
|
|
1504
|
|
|
|
|
|
|
package My::Custom::Array; |
1505
|
|
|
|
|
|
|
use strictures 2; |
1506
|
|
|
|
|
|
|
require Role::Tiny; |
1507
|
|
|
|
|
|
|
Role::Tiny->apply_roles_to_package( __PACKAGE__, |
1508
|
|
|
|
|
|
|
qw/ |
1509
|
|
|
|
|
|
|
List::Objects::WithUtils::Role::Array |
1510
|
|
|
|
|
|
|
List::Objects::WithUtils::Role::Array::WithJunctions |
1511
|
|
|
|
|
|
|
My::Custom::Array::Role |
1512
|
|
|
|
|
|
|
/ |
1513
|
|
|
|
|
|
|
); |
1514
|
|
|
|
|
|
|
|
1515
|
|
|
|
|
|
|
use Exporter (); |
1516
|
|
|
|
|
|
|
our @EXPORT = 'myarray'; |
1517
|
|
|
|
|
|
|
sub import { |
1518
|
|
|
|
|
|
|
# touch $a/$b in caller to avoid 'used only once' warnings: |
1519
|
|
|
|
|
|
|
my $pkg = caller; |
1520
|
|
|
|
|
|
|
{ no strict 'refs'; |
1521
|
|
|
|
|
|
|
${"${pkg}::a"} = ${"${pkg}::a"}; |
1522
|
|
|
|
|
|
|
${"${pkg}::b"} = ${"${pkg}::b"}; |
1523
|
|
|
|
|
|
|
} |
1524
|
|
|
|
|
|
|
goto &Exporter::import |
1525
|
|
|
|
|
|
|
} |
1526
|
|
|
|
|
|
|
|
1527
|
|
|
|
|
|
|
sub myarray { __PACKAGE__->new(@_) } |
1528
|
|
|
|
|
|
|
|
1529
|
|
|
|
|
|
|
=head1 SEE ALSO |
1530
|
|
|
|
|
|
|
|
1531
|
|
|
|
|
|
|
L |
1532
|
|
|
|
|
|
|
|
1533
|
|
|
|
|
|
|
L |
1534
|
|
|
|
|
|
|
|
1535
|
|
|
|
|
|
|
L |
1536
|
|
|
|
|
|
|
|
1537
|
|
|
|
|
|
|
L |
1538
|
|
|
|
|
|
|
|
1539
|
|
|
|
|
|
|
L |
1540
|
|
|
|
|
|
|
|
1541
|
|
|
|
|
|
|
L |
1542
|
|
|
|
|
|
|
|
1543
|
|
|
|
|
|
|
L |
1544
|
|
|
|
|
|
|
|
1545
|
|
|
|
|
|
|
L |
1546
|
|
|
|
|
|
|
|
1547
|
|
|
|
|
|
|
=head1 AUTHOR |
1548
|
|
|
|
|
|
|
|
1549
|
|
|
|
|
|
|
Jon Portnoy |
1550
|
|
|
|
|
|
|
|
1551
|
|
|
|
|
|
|
Portions of this code were contributed by Toby Inkster (CPAN: TOBYINK). |
1552
|
|
|
|
|
|
|
|
1553
|
|
|
|
|
|
|
Portions of this code are derived from L by Matthew Phillips |
1554
|
|
|
|
|
|
|
(MATTP), Graham Knop (HAARG) et al. |
1555
|
|
|
|
|
|
|
|
1556
|
|
|
|
|
|
|
Portions of this code are inspired by L-0.33 by Adam Kennedy (ADAMK), |
1557
|
|
|
|
|
|
|
Tassilo von Parseval, and Aaron Crane. |
1558
|
|
|
|
|
|
|
|
1559
|
|
|
|
|
|
|
L was inspired by Yanick Champoux in |
1560
|
|
|
|
|
|
|
L |
1561
|
|
|
|
|
|
|
|
1562
|
|
|
|
|
|
|
Licensed under the same terms as Perl. |
1563
|
|
|
|
|
|
|
|
1564
|
|
|
|
|
|
|
=cut |
1565
|
|
|
|
|
|
|
|