| List-Rubyish documentation | Contained in the List-Rubyish distribution. |
List::Rubyish - Array iterator like the Ruby
my $array_ref = [
{name => 'jkondo'},
{name => 'cinnamon'}
];
my $list = List::Rubyish->new($array_ref);
$list->size; #=> 2
my $first = $list->shift; #=> {name => 'jkondo'}
$list->push($first); #=> [{name => 'cinnamon'}, {name => 'jkondo'}];
# List::Rubyish provides much more useful methods. For more
# details, see the sections below.
DBIx::MoCo::List is very useful, However installation is complex.
List::Rubyish was made in order to enable use of DBIx::MoCo::List independently.
Dump the content of $self using Data::Dumper.
Sets the argument into $self, a refernce to an array blessed by
List::Rubyish, like the same name functions provided by Perl core,
then returns a List::Rubyish object.
my $list = List::Rubyish->new([qw(1 2 3)]); $list->push(4, 5); #=> [1, 2, 3, 4, 5] $list->unshift(0); #=> [0, 1, 2, 3, 4, 5]
They're almost the same as push()/unshift() described above
except that the argument shoud be a reference to an array.
my $list = List::Rubyish->new([1, 2, 3]); $list->concat([4, 5]); #=> [1, 2, 3, 4, 5] $list->prepend([0]); #=> [0, 1, 2, 3, 4, 5]
Pulls out the first/last element from $self, a refernce to an array
blessed by List::Rubyish, then returns it like the same name
functions in Perl core.
$list = List::Rubyish->new([1, 2, 3]); $list->shift; #=> 1 $list->pop; #=> 3 $list->dump #=> [2]
Returns the first/last element of $self, a refernce to an array
blessed by List::Rubyish. These methods aren't destructive contrary
to shift()/pop() method.
$list = List::Rubyish->new([1, 2, 3]); $list->first; #=> 1 $list->last; #=> 3 $list->dump #=> [1, 2, 3]
Returns the elements whose indexes are between $start and $end
as a List::Rubyish object.
$list = List::Rubyish->new([qw(1 2 3 4)]); $list->slice(1, 2) #=> [2, 3]
Bundles up the elements in each arguments into an array or a List::Rubyish object along with the context.
my $list = List::Rubyish->new([1, 2, 3]);
$list->zip([4, 5, 6], [7, 8, 9]);
#=> [[1, 4, 7], [2, 5, 8], [3, 6, 9]]
# When the numbers of each list are different...
$list = List::Rubyish->new([1, 2, 3]);
$list->zip([4, 5], [7, 8, 9]);
#=> [[1, 4, 7], [2, 5, 8], [3, undef, 9]]
my $list = List::Rubyish->new([1, 2]);
$list->zip([4, 5], [7, 8, 9]);
#=> [[1, 4, 7], [2, 5, 8]]
Deletes the same values as $value in $self, a refernce to an
array blessed by List::Rubyish, and returns the value if found. If
the value is not found in $self and $code is passed in, the code
is executed using the value as an argument to find the value to be
deleted.
$list = List::Rubyish->new([1, 2, 3, 2, 1]); $list->delete(2); #=> 2 $list->dump #=> [1, 3, 1]
Deletes the element at $pos and returns it.
$list = List::Rubyish->new([1, 2, 3, 2, 1]); $list->delete_at(3); #=> 2 $list->dump #=> [1, 2, 3, 1]
Deletes the elements if $code returns true value with each element
as an argument.
$list = List::Rubyish->new([1, 2, 3, 4]);
$list->delete_if(sub { ($_ % 2) == 0) });
$list->dump #=> [1, 3]
Executes folding calculation using $code through each element and
returns the result.
$list = List::Rubyish->new([1, 2, 3, 4]);
$list->inject(0, sub { $_[0] + $_[1] }); #=> 10
Joins all the elements by $delimiter.
$list = List::Rubyish->new([0 1 2 3]);
$list->join(', ') #=> '0, 1, 2, 3'
Executes $code with each index of $self, a refernce to an array
blessed by List::Rubyish.
$list = List::Rubyish->new([1, 2, 3]);
$list->each_index(sub { do_something($_) });
Executes $code with each value of $self, a refernce to an array
blessed by List::Rubyish.
$list = List::Rubyish->new([1, 2, 3]);
$list->each(sub { do_something($_) });
Executes $code with each element of $self, a refernce to an
array blessed by List::Rubyish using CORE::map() and returns the
results as a list or List::Rubyish object along with the context.
$list = List::Rubyish->new([1, 2, 3]);
$list->map(sub { $_ * 2 }); #=> [2, 4, 6]
An alias of collect() method described above.
Executes $code with each element of $self, a refernce to an
array blessed by List::Rubyish using CORE::grep() and returns the
results as a list or List::Rubyish object along with the context.
$list = List::Rubyish->new([qw(1 2 3 4)]);
$list->grep(sub { ($_ % 2) == 0 }); #=> [2, 4]
Returns the first value found in $self, a refernce to an array
blessed by List::Rubyish, as a result of $code..
$list = List::Rubyish->new([1, 2, 3, 4]);
$list->find(sub { ($_ % 2) == 0 }); #=> 2
Returns the values found in $self, a refernce to an array
blessed by List::Rubyish, as a result of $code..
$list = List::Rubyish->new([1, 2, 3, 4]);
$list->select(sub { ($_ % 2) == 0 }); #=> 2, 4
Returns index of given target or given code returns true.
$list = List::Rubyish->new([qw(foo bar baz)]);
$list->index_of('bar'); #=> 1
$list->index_of(sub { shift eq 'bar' }); #=> 1
Sorts out each element and returns the result as a list or List::Rubyish object along with the context.
$list = List::Rubyish->new([qw(3 2 4 1]);
$list->sort; #=> [1, 2, 3, 4]
$list->sort(sub { $_[1] <=> $_[0] }); #=> [4, 3, 2, 1]
Sorts out each element with Schwartzian transform returns the result as a list or List::Rubyish object along with the context.
$list = List::Rubyish->new([ [3], [2], [4], [1]]);
$list->sort_by(sub { $_->[0] }); #=> [[1], [2], [3], [4]]
$list->sort_by(sub { $_->[0] }, sub { $_[1} <=> $_[0] } ); #=> [[4], [3], [2], [1]]
Eliminates undefined values in $self, a refernce to an array
blessed by List::Rubyish.
$list = List::Rubyish->new([1, 2, undef, 3, undef, 4]); $list->compact; #=> [1, 2, 3, 4]
Returns the length of $self, a refernce to an array blessed by
List::Rubyish.
$list = List::Rubyish->new([qw(1 2 3 4)]); $list->length; #=> 4
An alias of length() method described above.
Returns a list or List::Rubyish object which is recursively flattened out.
$list = List::Rubyish->new([1, [2, 3, [4], 5]]); $list->flattern; #=> [1, 2, 3, 4, 5]
Returns true if $self, a refernce to an array blessed by
List::Rubyish, is empty.
Uniquifies the elements in $self, a refernce to an array blessed by
List::Rubyish, and returns the result.
$list = List::Rubyish->new([1, 2, 2, 3, 3, 4]) $list->uniq; #=> [1, 2, 3, 4]
Reduces the list by $code.
# finds the maximum value
$list = List::Rubyish->new([4, 1, 3, 2])
$list->reduce(sub { $_[0] > $_[1] ? $_[0] : $_[1] }); #=> 4
See List::Util to get to know about details of reduce().
Returns an reversely ordered $self, a refernce to an array blessed
by List::Rubyish.
$list = List::Rubyish->new([4, 1, 3, 2]) $list->reverse; #=> [2, 3, 1, 4]
Returns a duplicated $self, a refernce to an array blessed by
List::Rubyish.
Returns the sum of each element in $self, a refernce to an array
blessed by List::Rubyish.
$list = List::Rubyish->new([1, 2, 3, 4]); $list->sum; #=> 10
DBIx::MoCo::List, List::Util, List::MoreUtils, http://github.com/naoya/list-rubylike, http://d.hatena.ne.jp/naoya/20080419/1208579525, http://www.ruby-lang.org/ja/man/html/Enumerable.html
Junya Kondo, <jkondo@hatena.com>, Naoya Ito, <naoya@hatena.ne.jp>, Kentaro Kuribayashi, <kentarok@gmail.com>, Yuichi Tateno, <secondlife at hatena ne jp<gt>,
Kazuhiro Osawa <yappo <at> shibuya <döt> pl>
naoya, kentaro, tokuhirom, kan, lopnor
svn co http://svn.coderepos.org/share/lang/perl/List-Rubyish/trunk List-Rubyish
List::Rubyish is Subversion repository is hosted at http://coderepos.org/share/. patches and collaborators are welcome.
This library is free software; you can redistribute it and/or modify it under the same terms as Perl itself.
Copyright (C) Hatena Inc. All Rights Reserved.
| List-Rubyish documentation | Contained in the List-Rubyish distribution. |
package List::Rubyish; use strict; use warnings; use 5.008001; use overload '<<' => sub { my($self, $add) = @_; $add = [ $add ] unless ref($add) eq 'ARRAY' || ref($add) eq ref($self); $self->push(@$add); }, '>>' => sub { my($self, $add) = @_; if (ref($self) eq ref($add)) { my $tmp = $self; $self = $add; $add = $tmp; } elsif (ref($add) ne 'ARRAY') { $add = [ $add ]; } $self->unshift(@$add); }, '+' => sub { my($self, $add, $flag) = @_; $add = [ $add ] unless ref($add) eq 'ARRAY' || ref($add) eq ref($self); $self->add($add, $flag); }, fallback => 1; our $VERSION = '0.03'; use Carp qw/croak/; use List::Util (); use List::MoreUtils (); sub new { my $class = shift; $class = ref $class if ref $class; my $array = @_ > 0 ? (@_ == 1 && ref($_[0]) eq 'ARRAY') ? shift : [ @_ ] : []; bless $array, $class; } sub push { my $self = shift; push @$self, @_; $self; } sub unshift { my $self = shift; unshift @$self, @_; $self; } sub shift { shift @{$_[0]}; } sub pop { pop @{$_[0]}; } sub first { my ($self, $num) = @_; if (defined $num) { return $self->slice(0, $num - 1); } else { return $self->[0]; } } sub last { my ($self, $num) = @_; if (defined $num) { return $self->slice($self->_last_index - $num + 1, $self->_last_index); } else { return $self->[-1]; } } sub slice { my $self = CORE::shift; my ($start, $end) = @_; my $last = $#{$self}; if (defined $end) { if ($start == 0 && $last <= $end) { return $self; } else { $end = $last if $last < $end; return $self->new([ @$self[ $start .. $end ] ]); } } elsif (defined $start && 0 < $start && $last <= $start) { return $self->new([]); } else { return $self; } } sub dump { my $self = CORE::shift; require Data::Dumper; Data::Dumper->new([ $self->to_a ])->Purity(1)->Terse(1)->Dump; } sub zip { my $self = CORE::shift; my $array = \@_; my $index = 0; $self->collect(sub { my $ary = $self->new([$_]); $ary->push($_->[$index]) for @$array; $index++; $ary; }); } sub delete { my ($self, $value, $code) = @_; my $found = 0; if (ref $value eq 'CODE') { do { my $item = $self->shift; $value->($item) ? $found = 1 : $self->push($item) } for (0..$self->_last_index); } else { do { my $item = $self->shift; $item eq $value ? $found = 1 : $self->push($item) } for (0..$self->_last_index); } $found ? $value : ref $code eq 'CODE' ? do { local $_ = $value; return $code->($_) } : return ; } sub delete_at { my ($self, $pos) = @_; my $last_index = $self->_last_index; return if $pos > $last_index ; my $result; $_ == $pos ? $result = $self->shift : $self->push($self->shift) for 0..$last_index; return $result; } sub delete_if { my ($self, $code) = @_; croak "Argument must be a code" unless ref $code eq 'CODE'; my $last_index = $self->_last_index; for (0..$last_index) { my $item = $self->shift; local $_ = $item; $self->push($item) unless $code->($_); } return $self; } sub reject { my ($self, $code) = @_; return $self->dup->delete_if($code); } sub inject { my ($self, $result, $code) = @_; croak "Argument must be a code" unless ref $code eq 'CODE'; $result = $code->($result, $_) for @{$self->dup}; return $result; } sub join { my ($self, $delimiter) = @_; join $delimiter, @$self; } sub each_index { my ($self, $code) = @_; $self->new([ 0..$self->_last_index ])->each($code); } sub _last_index { my $self = CORE::shift; $self->length ? $self->length - 1 : 0; }; sub concat { my ($self, $array) = @_; $self->push(@$array); $self; } *append = \&concat; sub prepend { my ($self, $array) = @_; $self->unshift(@$array); $self; } sub _append_undestructive { my ($self, $array) = @_; $self->dup->push(@$array); } sub _prepend_undestructive { my ($self, $array) = @_; $self->dup->unshift(@$array); } sub add { my ($self, $array, $bool) = @_; $bool ? $self->_prepend_undestructive($array) : $self->_append_undestructive($array); } sub each { my ($self, $code) = @_; croak "Argument must be a code" unless ref $code eq 'CODE'; $code->($_) for @{$self->dup}; $self; } sub collect { my ($self, $code) = @_; croak "Argument must be a code" unless ref $code eq 'CODE'; my @collected = CORE::map &$code, @{$self->dup}; wantarray ? @collected : $self->new(\@collected); } *map = \&collect; sub grep { my ($self, $code) = @_; $code or return; my @grepped; if (!ref($code)) { for (@$self) { if (ref($_) eq 'HASH') { CORE::push @grepped, $_ if $_->{$code}; } else { CORE::push @grepped, $_ if $_->$code; } } } elsif (ref $code eq 'CODE') { @grepped = CORE::grep &$code, @$self; } else { croak "Invalid code"; } wantarray ? @grepped : $self->new(\@grepped); } sub find { my ($self, $cond) = @_; my $code = (ref $cond and ref $cond eq 'CODE') ? $cond : sub { $_ eq $cond }; for (@$self) { &$code and return $_ } return; } *detect = \&find; sub select { my ($self, $code) = @_; croak "Argument must be a code" unless ref $code eq 'CODE'; return $self unless $self->size; my $last_index = $self->_last_index; my $new = $self->dup; for (0..$last_index) { my $item = $new->shift; local $_ = $item; $new->push($item) if $code->($_); } return $new; } *find_all = \&select; sub index_of { my ($self, $target) = @_; my $code = (ref $target eq 'CODE') ? $target : sub { CORE::shift eq $target }; for (my $i = 0; $i < $self->length; $i++) { $code->($self->[$i]) and return $i; } return; } sub sort { my ($self, $code) = @_; my @sorted = $code ? CORE::sort { $code->($a, $b) } @$self : CORE::sort @$self; wantarray ? @sorted : $self->new(\@sorted); } sub sort_by { my ($self, $code, $cmp) = @_; my @sorted = $cmp ? CORE::map { $_->[1] } CORE::sort { $cmp->($a->[0], $b->[0]) } CORE::map { [$code->($_), $_] } @$self : CORE::map { $_->[1] } CORE::sort { $a->[0] <=> $b->[0] } CORE::map { [$code->($_), $_] } @$self; wantarray ? @sorted : $self->new(\@sorted); } sub compact { CORE::shift->grep(sub { defined }); } sub length { scalar @{$_[0]}; } *size = \&length; sub flatten { my $self = CORE::shift; $self->collect(sub { _flatten($_) }); } sub _flatten { my $element = CORE::shift; (ref $element and ref $element eq 'ARRAY') ? CORE::map { _flatten($_) } @$element : $element; } sub is_empty { !$_[0]->length; } sub uniq { my $self = CORE::shift; $self->new([ List::MoreUtils::uniq(@$self) ]); } sub reduce { my ($self, $code) = @_; croak "Argument must be a code" unless ref $code eq 'CODE'; List::Util::reduce { $code->($a, $b) } @$self; } sub to_a { my @unblessed = @{$_[0]}; \@unblessed; } sub as_list { # for Template::Iterator CORE::shift; } sub dup { __PACKAGE__->new($_[0]->to_a); } sub reverse { my $self = CORE::shift; $self->new([ reverse @$self ]); } sub sum { List::Util::sum @{$_[0]}; } 1; __END__