Skip to content

Commit

Permalink
improve first and grep methods in Mojo::Collection to be able to call…
Browse files Browse the repository at this point in the history
… methods
  • Loading branch information
kraih committed Sep 25, 2015
1 parent 7e9cd70 commit 168b13b
Show file tree
Hide file tree
Showing 3 changed files with 46 additions and 18 deletions.
4 changes: 3 additions & 1 deletion Changes
@@ -1,7 +1,9 @@

6.22 2015-09-25
6.22 2015-09-26
- Improved Mojo::JSON by reusing JSON::PP boolean constants.
- Improved uniq method in Mojo::Collection to accept a callback. (CandyAngel)
- Improved first and grep methods in Mojo::Collection to be able to call
methods.
- Improved support for empty attributes in Mojo::DOM::HTML.

6.21 2015-09-23
Expand Down
51 changes: 34 additions & 17 deletions lib/Mojo/Collection.pm
Expand Up @@ -27,18 +27,18 @@ sub each {
}

sub first {
my ($self, $cb) = @_;
my ($self, $cb) = (shift, shift);
return $self->[0] unless $cb;
return List::Util::first { $cb->($_) } @$self if ref $cb eq 'CODE';
return List::Util::first { $_ =~ $cb } @$self;
return List::Util::first { $_ =~ $cb } @$self if ref $cb eq 'Regexp';
return List::Util::first { $_->$cb(@_) } @$self;
}

sub flatten { $_[0]->new(_flatten(@{$_[0]})) }

sub grep {
my ($self, $cb) = @_;
return $self->new(grep { $cb->($_) } @$self) if ref $cb eq 'CODE';
return $self->new(grep { $_ =~ $cb } @$self);
my ($self, $cb) = (shift, shift);
return $self->new(grep { $_ =~ $cb } @$self) if ref $cb eq 'Regexp';
return $self->new(grep { $_->$cb(@_) } @$self);
}

sub join {
Expand Down Expand Up @@ -93,9 +93,9 @@ sub tap { shift->Mojo::Base::tap(@_) }
sub to_array { [@{shift()}] }

sub uniq {
my ($self, $cb) = @_;
my ($self, $cb) = (shift, shift);
my %seen;
return $self->new(grep { !$seen{$cb->($_)}++ } @$self) if $cb;
return $self->new(grep { !$seen{$_->$cb(@_)}++ } @$self) if $cb;
return $self->new(grep { !$seen{$_}++ } @$self);
}

Expand Down Expand Up @@ -192,11 +192,16 @@ to the callback and is also available as C<$_>.
my $first = $collection->first;
my $first = $collection->first(qr/foo/);
my $first = $collection->first(sub {...});
my $first = $collection->first($method);
my $first = $collection->first($method, @args);
Evaluate regular expression/callback for, or call method on, each element in
collection and return the first one that matched the regular expression, or for
which the callback/method returned true. The element will be the first argument
passed to the callback and is also available as C<$_>.
Evaluate regular expression or callback for each element in collection and
return the first one that matched the regular expression, or for which the
callback returned true. The element will be the first argument passed to the
callback and is also available as C<$_>.
# Longer version
my $first = $collection->first(sub { $_->$method(@args) });
# Find first value that contains the word "mojo"
my $interesting = $collection->first(qr/mojo/i);
Expand All @@ -218,11 +223,17 @@ all elements.
my $new = $collection->grep(qr/foo/);
my $new = $collection->grep(sub {...});
my $new = $collection->grep($method);
my $new = $collection->grep($method, @args);
Evaluate regular expression or callback for each element in collection and
create a new collection with all elements that matched the regular expression,
or for which the callback returned true. The element will be the first argument
passed to the callback and is also available as C<$_>.
Evaluate regular expression/callback for, or call method on, each element in
collection and create a new collection with all elements that matched the
regular expression, or for which the callback/method returned true. The element
will be the first argument passed to the callback and is also available as
C<$_>.
# Longer version
my $new = $collection->grep(sub { $_->$method(@args) });
# Find all values that contain the word "mojo"
my $interesting = $collection->grep(qr/mojo/i);
Expand Down Expand Up @@ -336,9 +347,15 @@ Turn collection into array reference.
my $new = $collection->uniq;
my $new = $collection->uniq(sub {...});
my $new = $collection->uniq($method);
my $new = $collection->uniq($method, @args);
Create a new collection without duplicate elements, using the string
representation of either the elements or the return value of the callback.
representation of either the elements or the return value of the
callback/method.
# Longer version
my $new = $collection->uniq(sub { $_->$method(@args) });
# "foo bar baz"
Mojo::Collection->new('foo', 'bar', 'bar', 'baz')->uniq->join(' ');
Expand Down
9 changes: 9 additions & 0 deletions t/mojo/collection.t
Expand Up @@ -46,6 +46,9 @@ is_deeply $collection->first(sub { ref $_ eq 'ARRAY' }), [3, 2], 'right result';
is $collection->first(sub { shift() < 5 }), 4, 'right result';
is $collection->first(qr/[1-4]/), 4, 'right result';
is $collection->first(sub { ref $_ eq 'CODE' }), undef, 'no result';
$collection = c(c(1, 2, 3), c(4, 5, 6), c(7, 8, 9));
is_deeply $collection->first(first => sub { $_ == 5 })->to_array, [4, 5, 6],
'right result';
$collection = c();
is $collection->first, undef, 'no result';
is $collection->first(sub {defined}), undef, 'no result';
Expand All @@ -69,6 +72,9 @@ is_deeply $collection->grep(sub { shift == 5 })->to_array, [5],
'right elements';
is_deeply $collection->grep(sub { $_ < 1 })->to_array, [], 'no elements';
is_deeply $collection->grep(sub { $_ > 9 })->to_array, [], 'no elements';
$collection = c(c(1, 2, 3), c(4, 5, 6), c(7, 8, 9));
is_deeply $collection->grep(first => sub { $_ >= 5 })->flatten->to_array,
[4, 5, 6, 7, 8, 9], 'right result';

# join
$collection = c(1, 2, 3);
Expand Down Expand Up @@ -156,6 +162,9 @@ is_deeply $collection->uniq->reverse->uniq->to_array, [5, 4, 3, 2, 1],
$collection = c([1, 2, 3], [3, 2, 1], [3, 1, 2]);
is_deeply $collection->uniq(sub { $_->[1] }), [[1, 2, 3], [3, 1, 2]],
'right result';
$collection = c(c(1, 2), c(1, 2), c(2, 1));
is_deeply $collection->uniq(join => ',')->flatten->to_array, [1, 2, 2, 1],
'right result';

# TO_JSON
is encode_json(c(1, 2, 3)), '[1,2,3]', 'right result';
Expand Down

0 comments on commit 168b13b

Please sign in to comment.