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 (or -1 if the array is empty).
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", "rotator".
$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", "rotator".
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 $rot = array(qw/cat sheep mouse/); $rot->(); ## 'cat' $rot->(); ## 'sheep' $rot->(); ## 'mouse' $rot->(); ## 'cat'
Returns an iterator that, when called, produces the next element in the array; when there are no elements left, the iterator returns to the start of the array.
See also "rotate", "rotate_in_place".
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.
$arr->visit(sub { warn "array contains: $_" });
Executes the given subroutine against each element sequentially; in practice this is much like "map", except the return value is thrown away.
Returns the original array object.
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.