File Coverage

lib/List/Objects/WithUtils/Role/Array.pm
Criterion Covered Total %
statement 204 204 100.0
branch 47 48 97.9
condition 4 6 66.7
subroutine 70 70 100.0
total 325 328 99.1


line stmt bran cond sub code
1         package List::Objects::WithUtils::Role::Array;
2 93     93 use strictures 1;
  93        
  93        
3          
4 93     93 use Carp ();
  93        
  93        
5          
6 93     93 use List::Util ();
  93        
  93        
7 93     93 use List::MoreUtils ();
  93        
  93        
8 93     93 use List::UtilsBy ();
  93        
  93        
9          
10 93     93 use Module::Runtime ();
  93        
  93        
11          
12 93     93 use Scalar::Util ();
  93        
  93        
13          
14         =pod
15        
16         =for Pod::Coverage ARRAY_TYPE blessed_or_pkg
17        
18         =begin comment
19        
20         Regarding blessed_or_pkg():
21         This is some nonsense to support autoboxing; if we aren't blessed, we're
22         autoboxed, in which case we appear to have no choice but to cheap out and
23         return the basic array type.
24        
25         =end comment
26        
27         =cut
28          
29         sub ARRAY_TYPE () { 'List::Objects::WithUtils::Array' }
30          
31         sub blessed_or_pkg {
32 74 100   74   Scalar::Util::blessed($_[0]) ?
33             $_[0] : Module::Runtime::use_module(ARRAY_TYPE)
34         }
35          
36          
37         sub __flatten_all {
38           ref $_[0] eq 'ARRAY'
39           || Scalar::Util::blessed($_[0])
40         # 5.8 doesn't have ->DOES()
41              && $_[0]->can('does')
42              && $_[0]->does('List::Objects::WithUtils::Role::Array') ?
43 27 100 66 27      map {; __flatten_all($_) } @{ $_[0] }
  17        
  6        
44           : $_[0]
45         }
46          
47         sub __flatten {
48 14     14   my $depth = shift;
49 44 100 66     CORE::map {
    100      
50 14           ref eq 'ARRAY'
51             || Scalar::Util::blessed($_)
52                && $_->can('does')
53                && $_->does('List::Objects::WithUtils::Role::Array') ?
54               $depth > 0 ? __flatten( $depth - 1, @$_ ) : $_
55               : $_
56           } @_
57         }
58          
59          
60 93     93 use Role::Tiny;
  93        
  93        
61          
62          
63 2     2 sub inflated_type { 'List::Objects::WithUtils::Hash' }
64          
65 2     2 sub is_mutable { 1 }
66 2     2 sub is_immutable { ! $_[0]->is_mutable }
67          
68         sub _try_coerce {
69 20     20   my (undef, $type, @vals) = @_;
70 20 100         Carp::confess "Expected a Type::Tiny type but got $type"
71               unless Scalar::Util::blessed $type;
72          
73 19         CORE::map {;
74 19           my $coerced;
75 19 100         $type->check($_) ? $_
    50      
    100      
76             : $type->assert_valid(
77                 $type->has_coercion ? ($coerced = $type->coerce($_)) : $_
78               ) ? $coerced
79               : Carp::confess "I should be unreachable!"
80           } @vals
81         }
82          
83         =pod
84        
85         =for Pod::Coverage TO_JSON type
86        
87         =cut
88          
89 2     2 sub type {
90         # array() has an empty ->type
91         }
92          
93         sub new {
94 470 100   470   if (my $blessed = Scalar::Util::blessed $_[0]) {
95 62           return bless [ @_[1 .. $#_] ], $blessed
96           }
97 408         bless [ @_[1 .. $#_] ], $_[0]
98         }
99          
100         sub copy {
101 2     2   my ($self) = @_;
102 2         blessed_or_pkg($self)->new(@$self);
103         }
104          
105         sub inflate {
106 1     1   my ($self) = @_;
107 1         my $pkg = blessed_or_pkg($self);
108 1         Module::Runtime::require_module( $pkg->inflated_type );
109 1         $pkg->inflated_type->new(@$self)
110         }
111          
112 3     3 sub unbless { [ @{ $_[0] } ] }
  3        
113 93     93 { no warnings 'once'; *TO_JSON = *unbless; }
  93        
  93        
114          
115         sub validated {
116 2     2   my ($self, $type) = @_;
117           blessed_or_pkg($_[0])->new(
118 2           CORE::map {; $self->_try_coerce($type, $_) } @$self
  5        
119           )
120         }
121          
122 87     87 sub all { @{ $_[0] } }
  87        
123          
124 32     32 sub count { CORE::scalar @{ $_[0] } }
  32        
125          
126 1     1 sub end { $#{ $_[0] } }
  1        
127          
128 93     93 { no warnings 'once';
  93        
  93        
129           *scalar = *count;
130           *export = *all;
131           *elements = *all;
132         }
133          
134 5 100   5 sub is_empty { CORE::scalar @{ $_[0] } ? 0 : 1 }
  5        
135          
136 21     21 sub get { $_[0]->[ $_[1] ] }
137 5     5 sub set { $_[0]->[ $_[1] ] = $_[2] ; $_[0] }
  4        
138          
139 1     1 sub random { $_[0]->[ rand @{ $_[0] } ] }
  1        
140          
141         sub kv {
142 1     1   my ($self) = @_;
143           blessed_or_pkg($self)->new(
144 1           map {; [ $_ => $self->[$_] ] } 0 .. $#$self
  4        
145           )
146         }
147          
148         sub head {
149           wantarray ?
150             (
151 2             $_[0]->[0],
152 3 100   3       blessed_or_pkg($_[0])->new( @{ $_[0] }[ 1 .. $#{$_[0]} ] )
  2        
153             )
154             : $_[0]->[0]
155         }
156          
157         sub tail {
158           wantarray ?
159             (
160 2             $_[0]->[-1],
161 3 100   3       blessed_or_pkg($_[0])->new( @{ $_[0] }[ 0 .. ($#{$_[0]} - 1) ] )
  2        
162             )
163             : $_[0]->[-1]
164         }
165          
166 2     2 sub pop { CORE::pop @{ $_[0] } }
  2        
167         sub push {
168 8     8   CORE::push @{ $_[0] }, @_[1 .. $#_];
  8        
169 7         $_[0]
170         }
171          
172 3     3 sub shift { CORE::shift @{ $_[0] } }
  3        
173         sub unshift {
174 4     4   CORE::unshift @{ $_[0] }, @_[1 .. $#_];
  4        
175 3         $_[0]
176         }
177          
178 1     1 sub clear { @{ $_[0] } = (); $_[0] }
  1        
  1        
179          
180 2     2 sub delete { scalar CORE::splice @{ $_[0] }, $_[1], 1 }
  2        
181          
182         sub delete_when {
183 2     2   my ($self, $sub) = @_;
184 2         my @removed;
185 2         my $i = @$self;
186 2         while ($i--) {
187 10 100         CORE::push @removed, CORE::splice @$self, $i, 1
188               if $sub->(local $_ = $self->[$i]);
189           }
190 2         blessed_or_pkg($_[0])->new(@removed)
191         }
192          
193         sub insert {
194 4     4   CORE::splice @{ $_[0] }, $_[1], 0, $_[2];
  4        
195 3         $_[0]
196         }
197          
198         sub join {
199 4         CORE::join(
200             ( defined $_[1] ? $_[1] : ',' ),
201 4 100   4     @{ $_[0] }
202           )
203         }
204          
205         sub map {
206           blessed_or_pkg($_[0])->new(
207 7     7     CORE::map {; $_[1]->($_) } @{ $_[0] }
  30        
  7        
208           )
209         }
210          
211         sub mapval {
212 2     2   my ($self, $sub) = @_;
213 2         my @copy = @$self;
214           blessed_or_pkg($_[0])->new(
215 2           CORE::map {; $sub->($_); $_ } @copy
  6        
  6        
216           )
217         }
218          
219         sub grep {
220           blessed_or_pkg($_[0])->new(
221 3     3     CORE::grep {; $_[1]->($_) } @{ $_[0] }
  11        
  3        
222           )
223         }
224          
225         sub sort {
226 7 100   7   if (defined $_[1]) {
227             return blessed_or_pkg($_[0])->new(
228 1             CORE::sort {; $_[1]->($a, $b) } @{ $_[0] }
  5        
  1        
229             )
230           }
231 6         return blessed_or_pkg($_[0])->new( CORE::sort @{ $_[0] } )
  6        
232         }
233          
234         sub reverse {
235 2         blessed_or_pkg($_[0])->new(
236 2     2     CORE::reverse @{ $_[0] }
237           )
238         }
239          
240         sub sliced {
241 2         blessed_or_pkg($_[0])->new(
242 2     2     @{ $_[0] }[ @_[1 .. $#_] ]
243           )
244         }
245          
246         sub splice {
247 7         blessed_or_pkg($_[0])->new(
248 7     7     CORE::splice @{ $_[0] }, $_[1], $_[2], @_[3 .. $#_]
249           )
250         }
251          
252         sub has_any {
253 13 100   13   unless (defined $_[1]) {
254 4           return CORE::scalar @{ $_[0] }
  4        
255           }
256          
257 9         &List::MoreUtils::any( $_[1], @{ $_[0] } )
  9        
258         }
259          
260         sub first {
261 2     2   &List::Util::first( $_[1], @{ $_[0] } )
  2        
262         }
263          
264         sub firstidx {
265 2     2   &List::MoreUtils::firstidx( $_[1], @{ $_[0] } )
  2        
266         }
267          
268         sub mesh {
269 5     5   my $max_idx = -1;
270 5 100       for (@_) { $max_idx = $#$_ if $max_idx < $#$_ }
  11        
271           blessed_or_pkg($_[0])->new(
272 4           CORE::map {;
273 21             my $idx = $_; map {; $_->[$idx] } @_
  21        
  45        
274             } 0 .. $max_idx
275           )
276         }
277          
278         sub natatime {
279 3     3   my $itr = List::MoreUtils::natatime($_[1], @{ $_[0] } );
  3        
280 3 100       if ($_[2]) {
281 1           while (my @nxt = $itr->()) { $_[2]->(@nxt) }
  3        
282           } else {
283 2           return $itr
284           }
285         }
286          
287         sub part {
288 4     4   my ($self, $code) = @_;
289 4         my @parts;
290 4         CORE::push @{ $parts[ $code->($_) ] }, $_ for @$self;
  42        
291 4         my $cls = blessed_or_pkg($self);
292           $cls->new(
293 4 100         map {; $cls->new(defined $_ ? @$_ : () ) } @parts
  12        
294           )
295         }
296          
297         sub bisect {
298 2     2   my ($self, $code) = @_;
299 2         my @parts = ( [], [] );
300 2 100       CORE::push @{ $parts[ $code->($_) ? 0 : 1 ] }, $_ for @$self;
  10        
301 2         my $cls = blessed_or_pkg($self);
302           $cls->new(
303 2           map {; $cls->new(@$_) } @parts
  4        
304           )
305         }
306          
307          
308         sub tuples {
309 8     8   my ($self, $size, $type) = @_;
310 8 100       $size = 2 unless defined $size;
311 8 100       Carp::confess "Expected a positive integer size but got $size"
312             if $size < 1;
313 7         my $itr = List::MoreUtils::natatime($size, @$self);
314 7         my @res;
315 7         while (my @nxt = $itr->()) {
316 16 100         if (defined $type) {
317 8             @nxt = CORE::map {; $self->_try_coerce($type, $_) }
  15        
318                 @nxt[0 .. ($size-1)]
319             }
320 13           CORE::push @res, [ @nxt ];
321           }
322 4         blessed_or_pkg($self)->new(@res)
323         }
324          
325         sub reduce {
326 4     4   List::Util::reduce { $_[1]->($a, $b) } @{ $_[0] }
  2     2  
  2        
327         }
328          
329         sub items_after {
330 2         blessed_or_pkg($_[0])->new(
331 2     2     &List::MoreUtils::after( $_[1], @{ $_[0] } )
332           )
333         }
334          
335         sub items_after_incl {
336 2         blessed_or_pkg($_[0])->new(
337 2     2     &List::MoreUtils::after_incl( $_[1], @{ $_[0] } )
338           )
339         }
340          
341         sub items_before {
342 2         blessed_or_pkg($_[0])->new(
343 2     2     &List::MoreUtils::before( $_[1], @{ $_[0] } )
344           )
345         }
346          
347         sub items_before_incl {
348 2         blessed_or_pkg($_[0])->new(
349 2     2     &List::MoreUtils::before_incl( $_[1], @{ $_[0] } )
350           )
351         }
352          
353         sub shuffle {
354 2         blessed_or_pkg($_[0])->new(
355 2     2     List::Util::shuffle( @{ $_[0] } )
356           )
357         }
358          
359         sub uniq {
360 2         blessed_or_pkg($_[0])->new(
361 2     2     List::MoreUtils::uniq( @{ $_[0] } )
362           )
363         }
364          
365         sub sort_by {
366 4         blessed_or_pkg($_[0])->new(
367 4     4     &List::UtilsBy::sort_by( $_[1], @{ $_[0] } )
368           )
369         }
370          
371         sub nsort_by {
372 1         blessed_or_pkg($_[0])->new(
373 1     1     &List::UtilsBy::nsort_by( $_[1], @{ $_[0] } )
374           )
375         }
376          
377         sub uniq_by {
378 1         blessed_or_pkg($_[0])->new(
379 1     1     &List::UtilsBy::uniq_by( $_[1], @{ $_[0] } )
380           )
381         }
382          
383         sub flatten_all {
384 3     3   CORE::map {; __flatten_all($_) } @{ $_[0] }
  10        
  3        
385         }
386          
387         sub flatten {
388 7         __flatten(
389             ( defined $_[1] ? $_[1] : 0 ),
390 7 100   7     @{ $_[0] }
391           )
392         }
393          
394         print
395           qq[<Schroedingers_hat> My sleeping pattern is cryptographically secure.\n]
396         unless caller;
397         1;
398          
399         =pod
400        
401         =head1 NAME
402        
403         List::Objects::WithUtils::Role::Array - Array manipulation methods
404        
405         =head1 SYNOPSIS
406        
407         ## Via List::Objects::WithUtils::Array ->
408         use List::Objects::WithUtils 'array';
409        
410         my $array = array(qw/ a b c /);
411        
412         $array->push(qw/ d e f /);
413        
414         my @upper = $array->map(sub { uc })->all;
415        
416         if ( $array->has_any(sub { $_ eq 'a' }) ) {
417         ...
418         }
419        
420         my $sum = array(1 .. 10)->reduce(sub { $_[0] + $_[1] });
421        
422         # See below for full list of methods
423        
424         ## As a Role ->
425         use Role::Tiny::With;
426         with 'List::Objects::WithUtils::Role::Array';
427        
428         =head1 DESCRIPTION
429        
430         A L<Role::Tiny> role defining methods for creating and manipulating ARRAY-type
431         objects.
432        
433         L<List::Objects::WithUtils::Array> consumes this role (along with
434         L<List::Objects::WithUtils::Role::Array::WithJunctions>) to provide B<array()> object
435         methods.
436        
437         In addition to the methods documented below, these objects provide a
438         C<TO_JSON> method exporting a plain ARRAY-type reference for convenience when
439         feeding L<JSON::Tiny> or similar.
440        
441         =head2 Basic array methods
442        
443         =head3 new
444        
445         Constructs a new ARRAY-type object.
446        
447         =head3 copy
448        
449         Returns a shallow clone of the current object.
450        
451         =head3 count
452        
453         Returns the number of elements in the array.
454        
455         =head3 end
456        
457         Returns the last index of the array.
458        
459         =head3 is_empty
460        
461         Returns boolean true if the array is empty.
462        
463         =head3 is_mutable
464        
465         Returns boolean true if the hash is mutable; immutable subclasses can override
466         to provide a negative value.
467        
468         =head3 is_immutable
469        
470         The opposite of L</is_mutable>. (Subclasses do not need to override so long as
471         L</is_mutable> returns a correct value.)
472        
473         =head3 scalar
474        
475         See L</count>.
476        
477         =head3 inflate
478        
479         my $hash = $array->inflate;
480         # Same as:
481         # my $hash = hash( $array->all )
482        
483         Inflates an array-type object to a hash-type object.
484        
485         Returns an L</inflated_type> object; by default this is a
486         L<List::Objects::WithUtils::Hash>.
487        
488         Throws an exception if the array contains an odd number of elements.
489        
490         =head3 inflated_type
491        
492         The class name that objects are blessed into when calling L</inflate>;
493         subclasses can override to provide their own hash-type objects.
494        
495         Defaults to L<List::Objects::WithUtils::Hash>.
496        
497         =head3 unbless
498        
499         Returns a plain C</ARRAY> reference (shallow clone).
500        
501         =head2 Methods that manipulate the list
502        
503         =head3 clear
504        
505         Delete all elements from the array.
506        
507         Returns the newly-emptied array object.
508        
509         =head3 delete
510        
511         Splices a given index out of the array.
512        
513         Returns the removed value.
514        
515         =head3 delete_when
516        
517         $array->delete_when( sub { $_ eq 'foo' } );
518        
519         Splices all items out of the array for which the given subroutine evaluates to
520         true.
521        
522         Returns a new array object containing the deleted values (possibly none).
523        
524         =head3 insert
525        
526         $array->insert( $position, $value );
527        
528         Inserts a value at a given position.
529        
530         Returns the array object.
531        
532         =head3 pop
533        
534         Pops the last element off the array and returns it.
535        
536         =head3 push
537        
538         Pushes elements to the end of the array.
539        
540         Returns the array object.
541        
542         =head3 set
543        
544         $array->set( $index, $value );
545        
546         Takes an array element and a new value to set.
547        
548         Returns the array object.
549        
550         =head3 shift
551        
552         Shifts the first element off the beginning of the array and returns it.
553        
554         =head3 unshift
555        
556         Adds elements to the beginning of the array.
557        
558         Returns the array object.
559        
560         =head3 splice
561        
562         # 2-arg splice (remove elements):
563         my $spliced = $array->splice(0, 2)
564         # 3-arg splice (replace):
565         $array->splice(0, 1, 'abc');
566        
567         Performs a C<splice()> on the current list and returns a new array object
568         consisting of the items returned from the splice.
569        
570         The existing array is modified in-place.
571        
572         =head3 validated
573        
574         use Types::Standard -all;
575         my $valid = array(qw/foo bar baz/)->validated(Str);
576        
577         Accepts a L<Type::Tiny> type, against which each element of the current array
578         will be checked before being added to a new array. Returns the new array.
579        
580         If the element fails the type check but can be coerced, the coerced value will
581         be added to the new array.
582        
583         Dies with a stack trace if the value fails type checks and can't be coerced.
584        
585         (You probably want an B<array_of> object from
586         L<List::Objects::WithUtils::Array::Typed> instead.)
587        
588         See: L<Types::Standard>, L<List::Objects::Types>
589        
590         =head2 Methods that retrieve items
591        
592         =head3 all
593        
594         Returns all elements in the array as a plain list.
595        
596         =head3 bisect
597        
598         my ($true, $false) = array( 1 .. 10 )
599         ->bisect(sub { $_ >= 5 })
600         ->all;
601         my @bigger = $true->all; # ( 5 .. 10 )
602         my @smaller = $false->all; # ( 1 .. 4 )
603        
604         Like L</part>, but creates an array-type object containing two
605         partitions; the first contains all items for which the subroutine evaluates to
606         true, the second contains the remaining items.
607        
608         =head3 elements
609        
610         Same as L</all>; included for consistency with similar array-type object
611         classes.
612        
613         =head3 export
614        
615         Same as L</all>; included for consistency with hash-type objects.
616        
617         =head3 flatten
618        
619         Flatten array objects to plain lists, possibly recursively.
620        
621         C<flatten> without arguments is the same as L</all>:
622        
623         my @flat = array( 1, 2, [ 3, 4 ] )->flatten;
624         # @flat = ( 1, 2, [ 3, 4 ] );
625        
626         If a depth is specified, sub-arrays are recursively flattened until the
627         specified depth is reached:
628        
629         my @flat = array( 1, 2, [ 3, 4 ] )->flatten(1);
630         # @flat = ( 1, 2, 3, 4 );
631        
632         my @flat = array( 1, 2, [ 3, 4, [ 5, 6 ] ] )->flatten(1);
633         # @flat = ( 1, 2, 3, 4, [ 5, 6 ] );
634        
635         This works with both ARRAY-type references and array objects:
636        
637         my @flat = array( 1, 2, [ 3, 4, array( 5, 6 ) ] )->flatten(2);
638         # @flat = ( 1, 2, 3, 4, 5, 6 );
639        
640         (Specifically, consumers of this role are flattened; other ARRAY-type objects
641         are left alone.)
642        
643         See L</flatten_all> for flattening to an unlimited depth.
644        
645         =head3 flatten_all
646        
647         Returns a plain list consisting of all sub-arrays recursively
648         flattened. Also see L</flatten>.
649        
650         =head3 get
651        
652         Returns the array element corresponding to a specified index.
653        
654         =head3 head
655        
656         my ($first, $rest) = $array->head;
657        
658         In list context, returns the first element of the list, and a new array-type
659         object containing the remaining list. The original object's list is untouched.
660        
661         In scalar context, returns just the first element of the array:
662        
663         my $first = $array->head;
664        
665         =head3 tail
666        
667         Similar to L</head>, but returns either the last element and a new array-type
668         object containing the remaining list (in list context), or just the last
669         element of the list (in scalar context).
670        
671         =head3 kv
672        
673         Returns an array-type object containing key/value pairs as (unblessed) ARRAYs;
674         this is much like L<List::Objects::WithUtils::Role::Hash/"kv">, except the
675         array index is the key.
676        
677         =head3 join
678        
679         my $str = $array->join(' ');
680        
681         Joins the array's elements and returns the joined string.
682        
683         Defaults to ',' if no delimiter is specified.
684        
685         =head3 mesh
686        
687         my $meshed = array(qw/ a b c /)->mesh(
688         array( 1 .. 3 )
689         );
690         $meshed->all; # 'a', 1, 'b', 2, 'c', 3
691        
692         Takes array references or objects and returns a new array object consisting of
693         one element from each array, in turn, until all arrays have been traversed
694         fully.
695        
696         You can mix and match references and objects freely:
697        
698         my $meshed = array(qw/ a b c /)->mesh(
699         array( 1 .. 3 ),
700         [ qw/ foo bar baz / ],
701         );
702        
703         =head3 part
704        
705         my $parts = array( 1 .. 8 )->part(sub { $i++ % 2 });
706         # Returns array objects:
707         $parts->get(0)->all; # 1, 3, 5, 7
708         $parts->get(1)->all; # 2, 4, 6, 8
709        
710         Takes a subroutine that indicates into which partition each value should be
711         placed.
712        
713         Returns an array-type object containing partitions represented as array-type
714         objects, as seen above.
715        
716         Skipped partitions are empty array objects:
717        
718         my $parts = array(qw/ foo bar /)->part(sub { 1 });
719         $parts->get(0)->is_empty; # true
720         $parts->get(1)->is_empty; # false
721        
722         The subroutine is passed the value we are operating on, or you can use the
723         topicalizer C<$_>:
724        
725         array(qw/foo bar baz 1 2 3/)
726         ->part(sub { m/^[0-9]+$/ ? 0 : 1 })
727         ->get(1)
728         ->all; # 'foo', 'bar', 'baz'
729        
730         =head3 random
731        
732         Returns a random element from the array.
733        
734         =head3 reverse
735        
736         Returns a new array object consisting of the reversed list of elements.
737        
738         =head3 shuffle
739        
740         my $shuffled = $array->shuffle;
741        
742         Returns a new array object containing the shuffled list.
743        
744         =head3 sliced
745        
746         my $slice = $array->sliced(1, 3, 5);
747        
748         Returns a new array object consisting of the elements retrived
749         from the specified indexes.
750        
751         =head3 tuples
752        
753         my $tuples = array(1 .. 7)->tuples(2);
754         # Returns:
755         # array(
756         # [ 1, 2 ],
757         # [ 3, 4 ],
758         # [ 5, 6 ],
759         # [ 7 ],
760         # )
761        
762         Simple sugar for L</natatime>; returns a new array object consisting of tuples
763         (unblessed ARRAY references) of the specified size (defaults to 2).
764        
765         C<tuples> accepts L<Type::Tiny> types as an optional second parameter; if
766         specified, items in tuples are checked against the type and a coercion is
767         attempted if the initial type-check fails:
768        
769         use Types::Standard -all;
770         my $tuples = array(1 .. 7)->tuples(2 => Int);
771        
772         A stack-trace is thrown if a value in a tuple cannot be made to validate.
773        
774         See: L<Types::Standard>, L<List::Objects::Types>
775        
776         =head2 Methods that find items
777        
778         =head3 grep
779        
780         my $matched = $array->grep(sub { $_[0] =~ /foo/ });
781        
782         Returns a new array object consisting of the list of elements for which the
783         given subroutine evaluated to true. C<$_[0]> is the element being operated
784         on; you can also use the topicalizer C<$_>.
785        
786         =head3 first
787        
788         my $arr = array( qw/ ab bc bd de / );
789         my $first = $arr->first(sub { /^b/ }); ## 'bc'
790        
791         Returns the first element of the list for which the given sub evaluates to
792         true. C<$_> is set to each element, in turn, until a match is found (or we run
793         out of possibles).
794        
795         =head3 firstidx
796        
797         Like L</first>, but return the index of the first successful match.
798        
799         =head3 has_any
800        
801         if ( $array->has_any(sub { $_ eq 'foo' }) ) {
802         ...
803         }
804        
805         If passed no arguments, returns the same thing as L</count>.
806        
807         If passed a sub, returns boolean true if the sub is true for any element
808         of the array; see L<List::MoreUtils/"any">.
809        
810         C<$_> is set to the element being operated upon.
811        
812         =head3 items_after
813        
814         my $after = array( 1 .. 10 )->items_after(sub { $_ == 5 });
815         ## $after contains [ 6, 7, 8, 9, 10 ]
816        
817         Returns a new array object consisting of the elements of the original list
818         that occur after the first position for which the given sub evaluates to true.
819        
820         =head3 items_after_incl
821        
822         Like L</items_after>, but include the item that evaluated to true.
823        
824         =head3 items_before
825        
826         The opposite of L</items_after>.
827        
828         =head3 items_before_incl
829        
830         The opposite of L</items_after_incl>.
831        
832         =head2 Methods that iterate the list
833        
834         =head3 map
835        
836         my $lowercased = $array->map(sub { lc });
837         # Same as:
838         my $lowercased = $array->map(sub { lc $_[0] });
839        
840         Evaluates a given subroutine for each element of the array, and returns a new
841         array object. C<$_[0]> is the element being operated on; you can also use
842         the topicalizer C<$_>.
843        
844         Also see L</mapval>.
845        
846         =head3 mapval
847        
848         my $orig = array(1, 2, 3);
849         my $incr = $orig->mapval(sub { ++$_ });
850        
851         $incr->all; # (2, 3, 4)
852         $orig->all; # Still untouched
853        
854         An alternative to L</map>. C<$_> is a copy, rather than an alias to the
855         current element, and the result is retrieved from the altered C<$_> rather
856         than the return value of the block.
857        
858         This feature is borrowed from L<Data::Munge> by Lukas Mai (CPAN: MAUKE).
859        
860         =head3 natatime
861        
862         my $iter = array( 1 .. 7 )->natatime(3);
863         $iter->(); ## ( 1, 2, 3 )
864         $iter->(); ## ( 4, 5, 6 )
865         $iter->(); ## ( 7 )
866        
867         array( 1 .. 7 )->natatime(3, sub { my @vals = @_; ... });
868        
869         Returns an iterator that, when called, produces a list containing the next
870         'n' items.
871        
872         If given a coderef as a second argument, it will be called against each
873         bundled group.
874        
875         =head3 reduce
876        
877         my $sum = array(1,2,3)->reduce(sub { $_[0] + $_[1] });
878        
879         Reduces the array by calling the given subroutine for each element of the
880         list. See L<List::Util/"reduce">.
881        
882         =head2 Methods that sort the list
883        
884         =head3 sort
885        
886         my $sorted = $array->sort(sub { $_[0] cmp $_[1] });
887        
888         Returns a new array object consisting of the list sorted by the given
889         subroutine. C<$_[0]> and C<$_[1]> are equivalent to C<$a> and C<$b> in a
890         normal sort() call.
891        
892         =head3 sort_by
893        
894         my $array = array(
895         { id => 'a' },
896         { id => 'c' },
897         { id => 'b' },
898         );
899         my $sorted = $array->sort_by(sub { $_->{id} });
900        
901         Returns a new array object consisting of the list of elements sorted via a
902         stringy comparison using the given sub.
903         See L<List::UtilsBy>.
904        
905         =head3 nsort_by
906        
907         Like L</sort_by>, but using numerical comparison.
908        
909         =head3 uniq
910        
911         my $unique = $array->uniq;
912        
913         Returns a new array object containing only unique elements from the original
914         array.
915        
916         =head3 uniq_by
917        
918         my $array = array(
919         { id => 'a' },
920         { id => 'a' },
921         { id => 'b' },
922         );
923         my $unique = $array->uniq_by(sub { $_->{id} });
924        
925         Returns a new array object consisting of the list of elements for which the
926         given sub returns unique values.
927        
928         =head1 SEE ALSO
929        
930         L<List::Objects::WithUtils>
931        
932         L<List::Objects::WithUtils::Array>
933        
934         L<List::Objects::WithUtils::Role::Array::WithJunctions>
935        
936         L<List::Objects::WithUtils::Array::Immutable>
937        
938         L<List::Objects::WithUtils::Array::Typed>
939        
940         L<Data::Perl>
941        
942         L<List::Util>
943        
944         L<List::MoreUtils>
945        
946         L<List::UtilsBy>
947        
948         =head1 AUTHOR
949        
950         Jon Portnoy <avenj@cobaltirc.org>
951        
952         Portions of this code are derived from L<Data::Perl> by Matthew Phillips
953         (CPAN: MATTP), haarg et al
954        
955         Licensed under the same terms as Perl.
956        
957         =cut
958          
959