Skip to content

Commit

Permalink
Add range() to Mojo::Collection
Browse files Browse the repository at this point in the history
  • Loading branch information
Jan Henning Thorsen committed Jun 5, 2019
1 parent 0aa984a commit 16cd641
Show file tree
Hide file tree
Showing 2 changed files with 46 additions and 2 deletions.
32 changes: 31 additions & 1 deletion lib/Mojo/Collection.pm
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,16 @@ sub new {
return bless [@_], ref $class || $class;
}

sub range {
my $self = shift;
my ($begin, $end)
= map { local $_ = $_ < 0 ? @$self + $_ : $_; $_ < 0 ? 0 : $_ }
($_[0] // 0, $_[1] // int @$self);
return $self->new if $begin >= @$self || $end == 0;
$end = @$self - 1 if $end >= @$self;
return $self->new(@$self[$begin .. $end]);
}

sub reduce {
my $self = shift;
@_ = (@_, @$self);
Expand Down Expand Up @@ -96,7 +106,7 @@ sub uniq {
my ($self, $cb) = (shift, shift);
my %seen;
return $self->new(grep { !$seen{$_->$cb(@_) // ''}++ } @$self) if $cb;
return $self->new(grep { !$seen{$_ // ''}++ } @$self);
return $self->new(grep { !$seen{$_ // ''}++ } @$self);
}

sub with_roles { shift->Mojo::Base::with_roles(@_) }
Expand Down Expand Up @@ -281,6 +291,26 @@ passed to the callback, and is also available as C<$_>.
Construct a new array-based L<Mojo::Collection> object.
=head2 range
my $new = $collection->range($begin, $end);
my $new = $collection->range(0, 2);
my $new = $collection->range(-4, -1);
my $new = $collection->range;
my $new = $collection->range;
Creates a new collection with the portion of the collection from C<$begin> to
C<$end> - C<$end> not included. C<$begin> will default to "0" unless specified,
and C<$end> will default to the L</size> of the collection. If C<$begin> is
greater than the L</size> of the collection, then an empty collection will be
returned. C<$begin> and C<$end> can also be negative, indicating an offset from
the end of the collection.
# "C D E"
c('A', 'B', 'C', 'D', 'E')->range(2)->join(' ');
c('A', 'B', 'C', 'D', 'E')->range(2, -1)->join(' ');
c('A', 'B', 'C', 'D', 'E')->range(-3, -1)->join(' ');
=head2 reduce
my $result = $collection->reduce(sub {...});
Expand Down
16 changes: 15 additions & 1 deletion t/mojo/collection.t
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,20 @@ is $collection->map('reverse')->map(join => "\n")->join("\n"),
is $collection->map(join => '-')->join("\n"), "1-2-3\n4-5-6\n7-8-9",
'right result';

# range
$collection = c(1 .. 5);
is_deeply $collection->range(0)->to_array, [1 .. 5], 'right result';
is_deeply $collection->range(0, 0)->to_array, [], 'right result';
is_deeply $collection->range(0, 4)->to_array, [1 .. 5], 'right result';
is_deeply $collection->range(0, 10)->to_array, [1 .. 5], 'right result';
is_deeply $collection->range(4)->to_array, [5], 'right result';
is_deeply $collection->range(5)->to_array, [], 'right result';
is_deeply $collection->range(5, 10)->to_array, [], 'right result';
is_deeply $collection->range(-1, -1)->to_array, [5], 'right result';
is_deeply $collection->range(-10, -7)->to_array, [], 'right result';
is_deeply $collection->range(-10, 10)->to_array, [1 .. 5], 'right result';
is_deeply $collection->range(-3)->to_array, [3 .. 5], 'right result';

# reverse
$collection = c(3, 2, 1);
is_deeply $collection->reverse->to_array, [1, 2, 3], 'right order';
Expand Down Expand Up @@ -140,7 +154,7 @@ $collection = c(qw(Test perl Mojo));
is_deeply $collection->sort(sub { uc(shift) cmp uc(shift) })->to_array,
[qw(Mojo perl Test)], 'right order';
$collection = c();
is_deeply $collection->sort->to_array, [], 'no elements';
is_deeply $collection->sort->to_array, [], 'no elements';
is_deeply $collection->sort(sub { $a cmp $b })->to_array, [], 'no elements';

# slice
Expand Down

0 comments on commit 16cd641

Please sign in to comment.