File Coverage

blib/lib/List/Objects/WithUtils/Role/Array.pm
Criterion Covered Total %
statement 398 400 99.5
branch 99 106 93.4
condition 29 38 76.3
subroutine 106 106 100.0
pod 74 76 97.3
total 706 726 97.2


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