File Coverage

blib/lib/List/Objects/WithUtils/Role/Array.pm
Criterion Covered Total %
statement 398 402 99.0
branch 99 108 91.6
condition 28 35 80.0
subroutine 106 106 100.0
pod 74 76 97.3
total 705 727 96.9


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