List::Objects::WithUtils::Role::Array - Array manipulation methods
## Via List::Objects::WithUtils::Array -> use List::Objects::WithUtils 'array'; my $array = array(qw/ a b c /); $array->push(qw/ d e f /); my @upper = $array->map(sub { uc })->all; if ( $array->has_any(sub { $_ eq 'a' }) ) { ... } my $sum = array(1 .. 10)->reduce(sub { $_[0] + $_[1] }); # See below for full list of methods ## As a Role -> use Role::Tiny::With; with 'List::Objects::WithUtils::Role::Array';
A Role::Tiny role defining methods for creating and manipulating ARRAY-type objects.
List::Objects::WithUtils::Array consumes this role (along with List::Objects::WithUtils::Role::Array::WithJunctions) to provide array() object methods.
In addition to the methods documented below, these objects provide a TO_JSON method exporting a plain ARRAY-type reference for convenience when feeding JSON::Tiny or similar.
TO_JSON
Constructs a new ARRAY-type object.
Returns a shallow clone of the current object.
Returns the number of elements in the array.
Returns the last index of the array.
Returns boolean true if the array is empty.
Returns boolean true if the hash is mutable; immutable subclasses can override to provide a negative value.
The opposite of "is_mutable". (Subclasses do not need to override so long as "is_mutable" returns a correct value.)
my $hash = $array->inflate; # Same as: # my $hash = hash( $array->all )
Inflates an array-type object to a hash-type object.
Returns an "inflated_type" object; by default this is a List::Objects::WithUtils::Hash.
Throws an exception if the array contains an odd number of elements.
The class name that objects are blessed into when calling "inflate"; subclasses can override to provide their own hash-type objects.
Defaults to List::Objects::WithUtils::Hash.
See "count".
Returns a plain /ARRAY reference (shallow clone).
/ARRAY
Delete all elements from the array.
Returns the newly-emptied array object.
Splices a given index out of the array.
Returns the removed value.
$array->delete_when( sub { $_ eq 'foo' } );
Splices all items out of the array for which the given subroutine evaluates to true.
Returns a new array object containing the deleted values (possibly none).
$array->insert( $position, $value );
Inserts a value at a given position.
Returns the array object.
Pops the last element off the array and returns it.
Pushes elements to the end of the array.
array(1 .. 3)->rotate_in_place; # 2, 3, 1 array(1 .. 3)->rotate_in_place(right => 1); # 3, 1, 2
Rotates the array in-place. A direction can be given.
Also see "rotate".
$array->set( $index, $value );
Takes an array element and a new value to set.
Shifts the first element off the beginning of the array and returns it.
Adds elements to the beginning of the array.
# 1- or 2-arg splice (remove elements): my $spliced = $array->splice(0, 2) # 3-arg splice (replace): $array->splice(0, 1, 'abc');
Performs a splice() on the current list and returns a new array object consisting of the items returned from the splice.
splice()
The existing array is modified in-place.
use Types::Standard -all; my $valid = array(qw/foo bar baz/)->validated(Str);
Accepts a Type::Tiny type, against which each element of the current array will be checked before being added to a new array. Returns the new array.
If the element fails the type check but can be coerced, the coerced value will be added to the new array.
Dies with a stack trace if the value fails type checks and can't be coerced.
(You probably want an array_of object from List::Objects::WithUtils::Array::Typed instead.)
See: Types::Standard, List::Objects::Types
Returns all elements in the array as a plain list.
my ($true, $false) = array( 1 .. 10 ) ->bisect(sub { $_ >= 5 }) ->all; my @bigger = $true->all; # ( 5 .. 10 ) my @smaller = $false->all; # ( 1 .. 4 )
Like "part", but creates an array-type object containing two partitions; the first contains all items for which the subroutine evaluates to true, the second contains the remaining items.
Same as "all"; included for consistency with similar array-type object classes.
Same as "all"; included for consistency with hash-type objects.
Flatten array objects to plain lists, possibly recursively.
flatten without arguments is the same as "all":
flatten
my @flat = array( 1, 2, [ 3, 4 ] )->flatten; # @flat = ( 1, 2, [ 3, 4 ] );
If a depth is specified, sub-arrays are recursively flattened until the specified depth is reached:
my @flat = array( 1, 2, [ 3, 4 ] )->flatten(1); # @flat = ( 1, 2, 3, 4 ); my @flat = array( 1, 2, [ 3, 4, [ 5, 6 ] ] )->flatten(1); # @flat = ( 1, 2, 3, 4, [ 5, 6 ] );
This works with both ARRAY-type references and array objects:
my @flat = array( 1, 2, [ 3, 4, array( 5, 6 ) ] )->flatten(2); # @flat = ( 1, 2, 3, 4, 5, 6 );
(Specifically, consumers of this role are flattened; other ARRAY-type objects are left alone.)
See "flatten_all" for flattening to an unlimited depth.
Returns a plain list consisting of all sub-arrays recursively flattened. Also see "flatten".
Returns the array element corresponding to a specified index.
my ($first, $rest) = $array->head;
In list context, returns the first element of the list, and a new array-type object containing the remaining list. The original object's list is untouched.
In scalar context, returns just the first element of the array:
my $first = $array->head;
Similar to "head", but returns either the last element and a new array-type object containing the remaining list (in list context), or just the last element of the list (in scalar context).
my $str = $array->join(' ');
Joins the array's elements and returns the joined string.
Defaults to ',' if no delimiter is specified.
Returns an array-type object containing key/value pairs as (unblessed) ARRAYs; this is much like "kv" in List::Objects::WithUtils::Role::Hash, except the array index is the key.
my $meshed = array(qw/ a b c /)->mesh( array( 1 .. 3 ) ); $meshed->all; # 'a', 1, 'b', 2, 'c', 3
Takes array references or objects and returns a new array object consisting of one element from each array, in turn, until all arrays have been traversed fully.
You can mix and match references and objects freely:
my $meshed = array(qw/ a b c /)->mesh( array( 1 .. 3 ), [ qw/ foo bar baz / ], );
my $parts = array( 1 .. 8 )->part(sub { $i++ % 2 }); # Returns array objects: $parts->get(0)->all; # 1, 3, 5, 7 $parts->get(1)->all; # 2, 4, 6, 8
Takes a subroutine that indicates into which partition each value should be placed.
Returns an array-type object containing partitions represented as array-type objects, as seen above.
Skipped partitions are empty array objects:
my $parts = array(qw/ foo bar /)->part(sub { 1 }); $parts->get(0)->is_empty; # true $parts->get(1)->is_empty; # false
The subroutine is passed the value we are operating on, or you can use the topicalizer $_:
$_
array(qw/foo bar baz 1 2 3/) ->part(sub { m/^[0-9]+$/ ? 0 : 1 }) ->get(1) ->all; # 'foo', 'bar', 'baz'
Returns a random element from the array.
Returns a new array object consisting of the reversed list of elements.
my $leftwards = $array->rotate; my $rightwards = $array->rotate(right => 1);
Returns a new array object containing the rotated list.
Also see "rotate_in_place".
my $shuffled = $array->shuffle;
Returns a new array object containing the shuffled list.
my $slice = $array->sliced(1, 3, 5);
Returns a new array object consisting of the elements retrived from the specified indexes.
my $tuples = array(1 .. 7)->tuples(2); # Returns: # array( # [ 1, 2 ], # [ 3, 4 ], # [ 5, 6 ], # [ 7 ], # )
Simple sugar for "natatime"; returns a new array object consisting of tuples (unblessed ARRAY references) of the specified size (defaults to 2).
tuples accepts Type::Tiny types as an optional second parameter; if specified, items in tuples are checked against the type and a coercion is attempted if the initial type-check fails:
tuples
use Types::Standard -all; my $tuples = array(1 .. 7)->tuples(2 => Int);
A stack-trace is thrown if a value in a tuple cannot be made to validate.
my $matched = $array->grep(sub { /foo/ });
Returns a new array object consisting of the list of elements for which the given subroutine evaluates to true. $_[0] is the element being operated on; you can also use the topicalizer $_.
$_[0]
my $matched = $array->indexes(sub { /foo/ });
Like "grep", but returns a new array object consisting of the list of indexes for which the given subroutine evaluates to true.
my $arr = array( qw/ ab bc bd de / ); my $first = $arr->first_where(sub { /^b/ }); ## 'bc'
Returns the first element of the list for which the given sub evaluates to true. $_ is set to each element, in turn, until a match is found (or we run out of possibles).
Like "first_where", but return the index of the first successful match.
An alias for "first_index".
Like "first_where", but returns the last successful match.
Like "first_index", but returns the index of the last successful match.
An alias for "last_index".
if ( $array->has_any(sub { $_ eq 'foo' }) ) { ... }
If passed no arguments, returns the same thing as "count".
If passed a sub, returns boolean true if the sub is true for any element of the array; see "any" in List::MoreUtils.
$_ is set to the element being operated upon.
my $first = array(qw/ a b c /); my $second = array(qw/ b c d /); my $intersection = $first->intersection($second);
Returns a new array object containing the list of values common between all given array-type objects (including the invocant).
The new array object is not sorted in any predictable order.
(It may be worth noting that an intermediate hash is used; objects that stringify to the same value will be taken to be the same.)
my $first = array(qw/ a b c d /); my $second = array(qw/ b c x /); my @diff = $first->diff($second)->sort->all; # (a, d, x)
The opposite of "intersection"; returns a new array object containing the list of values that are not common between all given array-type objects (including the invocant).
The same constraints as "intersection" apply.
my $after = array( 1 .. 10 )->items_after(sub { $_ == 5 }); ## $after contains [ 6, 7, 8, 9, 10 ]
Returns a new array object consisting of the elements of the original list that occur after the first position for which the given sub evaluates to true.
Like "items_after", but include the item that evaluated to true.
The opposite of "items_after".
The opposite of "items_after_incl".
my $lowercased = $array->map(sub { lc }); # Same as: my $lowercased = $array->map(sub { lc $_[0] });
Evaluates a given subroutine for each element of the array, and returns a new array object. $_[0] is the element being operated on; you can also use the topicalizer $_.
Also see "mapval".
my $orig = array(1, 2, 3); my $incr = $orig->mapval(sub { ++$_ }); $incr->all; # (2, 3, 4) $orig->all; # Still untouched
An alternative to "map". $_ is a copy, rather than an alias to the current element, and the result is retrieved from the altered $_ rather than the return value of the block.
This feature is borrowed from Data::Munge by Lukas Mai (CPAN: MAUKE).
my $iter = array( 1 .. 7 )->natatime(3); $iter->(); ## ( 1, 2, 3 ) $iter->(); ## ( 4, 5, 6 ) $iter->(); ## ( 7 ) array( 1 .. 7 )->natatime(3, sub { my @vals = @_; ... });
Returns an iterator that, when called, produces a list containing the next 'n' items.
If given a coderef as a second argument, it will be called against each bundled group.
my $sum = array(1,2,3)->reduce(sub { $_[0] + $_[1] });
Reduces the array by calling the given subroutine for each element of the list. See "reduce" in List::Util.
my $sorted = $array->sort(sub { $_[0] cmp $_[1] });
Returns a new array object consisting of the list sorted by the given subroutine. $_[0] and $_[1] are equivalent to $a and $b in a normal sort() call.
$_[1]
$a
$b
my $array = array( { id => 'a' }, { id => 'c' }, { id => 'b' }, ); my $sorted = $array->sort_by(sub { $_->{id} });
Returns a new array object consisting of the list of elements sorted via a stringy comparison using the given sub. See List::UtilsBy.
Uses List::UtilsBy::XS if available.
Like "sort_by", but using numerical comparison.
my $unique = $array->uniq;
Returns a new array object containing only unique elements from the original array.
(It may be worth noting that this takes place via an intermediate hash; objects that stringify to the same value are not unique, even if they are different objects. "uniq_by" plus "refaddr" in Scalar::Util may help you there.)
my $array = array( { id => 'a' }, { id => 'a' }, { id => 'b' }, ); my $unique = $array->uniq_by(sub { $_->{id} });
Returns a new array object consisting of the list of elements for which the given sub returns unique values.
Uses List::UtilsBy::XS if available; falls back to List::UtilsBy if not.
List::Objects::WithUtils
List::Objects::WithUtils::Array
List::Objects::WithUtils::Array::Immutable
List::Objects::WithUtils::Array::Typed
List::Objects::WithUtils::Role::Array::WithJunctions
Data::Perl
List::Util
List::MoreUtils
List::UtilsBy
Jon Portnoy <avenj@cobaltirc.org>
Portions of this code are derived from Data::Perl by Matthew Phillips (CPAN: MATTP), haarg et al
Licensed under the same terms as Perl.
To install List::Objects::WithUtils, copy and paste the appropriate command in to your terminal.
cpanm
cpanm List::Objects::WithUtils
CPAN shell
perl -MCPAN -e shell install List::Objects::WithUtils
For more information on module installation, please visit the detailed CPAN module installation guide.