Skip to content

srchulo/Mojo-Collection-Role-Transform

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

9 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

NAME

Mojo::Collection::Role::Transform - Transformations for Mojo::Collection

STATUS

Coverage Status

SYNOPSIS

my $c = Mojo::Collection->new(
  {
    name           => 'Bob',
    age            => 23,
    favorite_color => 'blue',
  },
  {
    name           => 'Alice',
    age            => 24,
    favorite_color => 'blue',
  },
  {
    name           => 'Eve',
    age            => 27,
    favorite_color => 'green',
  },
)->with_roles('+Transform');

# hash key is name, value is the original hash
my $name_to_person = $c->hashify(sub { $_->{name} });

# 23
say $name_to_person->{Bob}{age};

# 27
say $name_to_person->{Eve}{age};

# set your own value
my $name_to_favorite_color = $c->hashify(sub { $_->{name} }, sub { $_->{favorite_color} });

# blue
say $name_to_favorite_color->{Bob};

# green
say $name_to_favorite_color->{Eve};


# collect values with the same key in a Mojo::Collection
my $favorite_color_to_collection = $c->hashify_collect(sub { $_->{favorite_color} });

# $favorite_color_to_collection->{blue} contains Mojo::Collection of Bob and Alice hashes
# $favorite_color_to_collection->{green} contains Mojo::Collection of Eve hash

# says Bob, then Alice
for my $person ($favorite_color_to_collection->{blue}->each) {
  say $person->{name};
}


# Create a Mojo::Collection of Mojo::Collections, where all values in each inner
# Mojo::Collection share the same key
my $collections_by_favorite_color = $c->collect_by(sub { $_->{favorite_color} });
for my $favorite_color_collection ($collections_by_favorite_color->each) {
  say $favorite_color_collection->[0]->{favorite_color};

  for my $person ($favorite_color_collection->each) {
    say "\t$person->{name}";
  }
}

# output is
# blue
#     Bob
#     Alice
# green
#     Eve

DESCRIPTION

Mojo::Collection::Role::Transform provides methods that allow you to transform your Mojo::Collection in meaningful and flexible ways.

METHODS

hashify

  • hashify($get_keys_sub, [$get_value_sub])

    my $c = Mojo::Collection->new( { name => 'Bob', age => 23, favorite_color => 'blue', }, { name => 'Alice', age => 24, favorite_color => 'blue', }, { name => 'Eve', age => 27, favorite_color => 'green', }, )->with_roles('+Transform');

    hash key is name, value is the original hash

    my $name_to_person = $c->hashify(sub { $_->{name} });

    23

    say $name_to_person->{Bob}{age};

    27

    say $name_to_person->{Eve}{age};

    set your own value

    my $name_to_favorite_color = $c->hashify(sub { $->{name} }, sub { $->{favorite_color} });

    blue

    say $name_to_favorite_color->{Bob};

    green

    say $name_to_favorite_color->{Eve};

    return multiple keys as a list to create a multiple nested hashes based on the returned keys and their order

    my $name_to_age_favorite_color = $c->hashify(sub { @${qw(name age)} }, sub { $->{favorite_color} });

    blue

    say $name_to_favorite_color->{Bob}{23};

    green

    say $name_to_favorite_color->{Eve}{27};

"hashify" allows you to transform a Mojo::Collection into a single key or multi-key hash based on its elements. A unique key or list of keys may only have one value, so for any duplicate keys, the final element seen with that key will be the one that sets the value.

get_keys

"get_keys" is required and must return a single key or a list of keys. The return value of "get_keys" will be the keys used to ultimately access the value that is returned by "get_value" for the same element.

# return single key
my $hash = $c->hashify(sub { $_->{name} });
my $value = $hash->{$name};

# return multiple keys
my $hash = $c->hashify(sub { $_->{name}, $_->{age} });
my $value = $hash->{$name}{$age};

The current element is available via $_, or as the first argument to "get_keys".

get_value

"get_value" must return a single value for the current element in the Mojo::Collection.

my $name_to_age = $c->hashify(sub { $_->{name} }, sub { $_->{age} });
my $age = $name_to_age->{Bob};

The default is to return the current element:

# default get_value
sub { $_ }

# not passing in get_value uses the above subroutine to return the current collection element, in this case a hash
my $name_to_person = $c->hashify(sub { $_->{name} });
my $age = $name_to_person->{Bob}{age};

The current element is available via $_, or as the first argument to "get_value".

hashify_collect

  • hashify_collect($get_keys_sub, [$get_values_sub])

    my $c = Mojo::Collection->new( { name => 'Bob', age => 23, favorite_color => 'blue', }, { name => 'Alice', age => 24, favorite_color => 'blue', }, { name => 'Eve', age => 27, favorite_color => 'green', }, )->with_roles('+Transform');

    collect values with the same key in a Mojo::Collection

    my $favorite_color_to_collection = $c->hashify_collect(sub { $_->{favorite_color} });

    $favorite_color_to_collection->{blue} contains Mojo::Collection of Bob and Alice hashes

    $favorite_color_to_collection->{green} contains Mojo::Collection of Eve hash

    says Bob, then Alice

    for my $person ($favorite_color_to_collection->{blue}->each) { say $person->{name}; }

    provide your own get_values sub

    my $favorite_color_to_names = $c->hashify_collect(sub { $->{favorite_color} }, sub { $->{name} });

    $favorite_color_to_names->{blue} contains Mojo::Collection of 'Bob' and 'Alice'

    $favorite_color_to_names->{green} contains Mojo::Collection of 'Eve'

    return multiple values

    my $favorite_color_to_names_and_ages = $c->hashify_collect(sub { $->{favorite_color} }, sub { $->{name}, $_->{age} });

    $favorite_color_to_names_and_ages->{blue} contains Mojo::Collection of 'Bob', 23, 'Alice', 24

    $favorite_color_to_names_and_ages->{green} contains Mojo::Collection of 'Eve', 27

"hashify_collect" allows you to transform a Mojo::Collection into a single key or multi-key hash where the final value is a Mojo::Collection with all elements that match that key. "get_values" allows you to control which values are collected in the Mojo::Collection.

get_keys

"get_keys" is required and must return a single key or a list of keys. The return value of "get_keys" will be the keys used to ultimately access the Mojo::Collection of values that are returned by "get_values" for each element.

# return single key
my $hash = $c->hashify(sub { $_->{name} });
my $collection = $hash->{$name};

# return multiple keys
my $hash = $c->hashify(sub { $_->{name}, $_->{age} });
my $collection = $hash->{$name}{$age};

The current element is available via $_, or as the first argument to "get_keys".

get_values

"get_values" may return one or more values as a list for the current element in the Mojo::Collection.

# return single value
my $name_to_ages = $c->hashify(sub { $_->{name} }, sub { $_->{age} });
my $ages_collection = $name_to_ages->{Bob};

# return multiple values
my $name_to_ages_and_favorite_colors = $c->hashify(sub { $_->{name} }, sub { $_->{age}, $_->{favorite_color} });
my $ages_and_favorite_colors_collection = $name_to_ages_and_favorite_colors->{Bob};

The default is to return the current element:

# default get_value
sub { $_ }

# not passing in get_value uses the above subroutine to return the current collection element, in this case a hash
my $name_to_persons = $c->hashify(sub { $_->{name} });
my $person_collection = $name_to_persons->{Bob};

The current element is available via $_, or as the first argument to "get_values".

OPTIONS

flatten

# trivial example where returned values are wrapped in arrayrefs to demonstrate flatten
my $name_to_ages = $c->hashify({flatten => 1}, sub { $_->{name} }, sub { [$_->{age}] });

The "flatten" option flattens each resulting Mojo::Collection, meaning that it flattens nested collections/arrays recursively and creates a new collection with all elements. See "flatten" in Mojo::Collection for more details.

Internally, "flatten" is implemented differently for performance, but the end result is the same.

collect_by

  • collect_by($get_keys_sub, [$get_values_sub])

    my $c = Mojo::Collection->new( { name => 'Bob', age => 23, favorite_color => 'blue', }, { name => 'Alice', age => 24, favorite_color => 'blue', }, { name => 'Eve', age => 27, favorite_color => 'green', }, )->with_roles('+Transform');

    Create a Mojo::Collection of Mojo::Collections, where all values in each inner

    Mojo::Collection share the same key

    my $collections_by_favorite_color = $c->collect_by(sub { $_->{favorite_color} }); for my $favorite_color_collection ($collections_by_favorite_color->each) { say $favorite_color_collection->[0]->{favorite_color};

    for my $person ($favorite_color_collection->each) {
      say "\t$person->{name}";
    }
    

    }

    output is

    blue

    Bob

    Alice

    green

    Eve

    collect by multiple keys

    uses favorite_color and age as the keys

    my $collections_by_favorite_color_and_age = $c->collect_by(sub { $->{favorite_color}, $->{age} });

"collect_by" allows you to transform a Mojo::Collection into a Mojo::Collection of Mojo::Collections, where all elements of the inner collections share the same single key or list of keys. "get_values" allows you to control which values are collected in the Mojo::Collection.

get_keys

"get_keys" is required and must return a single key or a list of keys. The return value of "get_keys" will be the keys used group values that are returned by "get_values" into each inner Mojo::Collection.

# return single key
my $collections = $c->hashify(sub { $_->{name} });

# return multiple keys
my $collections = $c->hashify(sub { $_->{name}, $_->{age} });

The current element is available via $_, or as the first argument to "get_keys".

get_values

"get_values" may return one or more values as a list for the current element in the Mojo::Collection.

# return single value
my $collections_of_age = $c->hashify(sub { $_->{name} }, sub { $_->{age} });

# i.e.
# [ [23], [24], [27] ]

# return multiple values
my $collections_of_age_and_favorite_color = $c->hashify(sub { $_->{name} }, sub { $_->{age}, $_->{favorite_color} });

# i.e.
# [ [23, 'blue'], [24, 'blue'], [27, 'green'] ]

The default is to return the current element:

# default get_value
sub { $_ }

# not passing in get_value uses the above subroutine to return the current collection element, in this case a hash
my $collections = $c->hashify(sub { $_->{name} });

# i.e.
# [ [{ name => 'Bob', ...}], [{ name => 'Alice', ...}], [{name => 'Eve', ...}] ]

The current element is available via $_, or as the first argument to "get_values".

OPTIONS

flatten

# trivial example where returned values are wrapped in arrayrefs to demonstrate flatten
my $collections = $c->hashify({flatten => 1}, sub { 'key' }, sub { [$_->{age}] });

# i.e.
# [ [23, 24, 27] ]

The "flatten" option flattens each inner Mojo::Collection, meaning that it flattens nested collections/arrays recursively and creates a new collection with all elements. See "flatten" in Mojo::Collection for more details.

Internally, "flatten" is implemented differently for performance, but the end result is the same.

AUTHOR

Adam Hopkins srchulo@cpan.org

COPYRIGHT

Copyright 2019- Adam Hopkins

LICENSE

This library is free software; you can redistribute it and/or modify it under the same terms as Perl itself.

SEE ALSO

About

Transformations for Mojo::Collection

Resources

License

Stars

Watchers

Forks

Packages

No packages published

Languages