chain.rb Enumerator::Chain class See Copyright Notice in mruby.h
The Enumerable
mixin provides collection classes with several
traversal and searching methods, and with the ability to sort. The class
must provide a method `each`, which yields successive members of the
collection. If {Enumerable#max}, {#min}, or {#sort} is used, the objects in
the collection must also implement a meaningful `<=>` operator, as
these methods rely on an ordering between members of the collection.
@ISO 15.3.2
ISO 15.3.2.2.1
Passes each element of the collection to the given block. The method returns <code>true</code> if the block never returns <code>false</code> or <code>nil</code>. If the block is not given, Ruby adds an implicit block of <code>{ |obj| obj }</code> which will cause #all? to return +true+ when none of the collection members are +false+ or +nil+. If a pattern is supplied instead, the method returns whether <code>pattern === element</code> for every collection member. %w[ant bear cat].all? { |word| word.length >= 3 } #=> true %w[ant bear cat].all? { |word| word.length >= 4 } #=> false %w[ant bear cat].all?(/t/) #=> false [1, 2i, 3.14].all?(Numeric) #=> true [nil, true, 99].all? #=> false
# File mrbgems/mruby-enum-ext/mrblib/enum.rb, line 549 def all?(pat=NONE, &block) if pat != NONE self.each{|*val| return false unless pat === val.__svalue} elsif block self.each{|*val| return false unless block.call(*val)} else self.each{|*val| return false unless val.__svalue} end true end
ISO 15.3.2.2.2
Passes each element of the collection to the given block. The method returns <code>true</code> if the block ever returns a value other than <code>false</code> or <code>nil</code>. If the block is not given, Ruby adds an implicit block of <code>{ |obj| obj }</code> that will cause #any? to return +true+ if at least one of the collection members is not +false+ or +nil+. If a pattern is supplied instead, the method returns whether <code>pattern === element</code> for any collection member. %w[ant bear cat].any? { |word| word.length >= 3 } #=> true %w[ant bear cat].any? { |word| word.length >= 4 } #=> true %w[ant bear cat].any?(/d/) #=> false [nil, true, 99].any?(Integer) #=> true [nil, true, 99].any? #=> true [].any? #=> false
# File mrbgems/mruby-enum-ext/mrblib/enum.rb, line 582 def any?(pat=NONE, &block) if pat != NONE self.each{|*val| return true if pat === val.__svalue} elsif block self.each{|*val| return true if block.call(*val)} else self.each{|*val| return true if val.__svalue} end false end
# File mrbgems/mruby-enum-chain/mrblib/chain.rb, line 6 def chain(*args) Enumerator::Chain.new(self, *args) end
Call the given block for each element which is yield by each
.
Append all values of each block together and return this value.
ISO 15.3.2.2.3
# File mrblib/enum.rb, line 59 def collect(&block) return to_enum :collect unless block ary = [] self.each{|*val| ary.push(block.call(*val))} ary end
Returns the number of items in enum
through enumeration. If an
argument is given, the number of items in enum
that are equal
to item
are counted. If a block is given, it counts the
number of elements yielding a true value.
# File mrbgems/mruby-enum-ext/mrblib/enum.rb, line 249 def count(v=NONE, &block) count = 0 if block self.each do |*val| count += 1 if block.call(*val) end else if v == NONE self.each { count += 1 } else self.each do |*val| count += 1 if val.__svalue == v end end end count end
Calls block for each element of enum repeatedly
n times or forever if none or nil
is given. If a
non-positive number is given or the collection is empty, does nothing.
Returns nil
if the loop has finished without getting
interrupted.
#cycle saves elements in an internal array so changes to enum after the first pass have no effect.
If no block is given, an enumerator is returned instead.
a = ["a", "b", "c"] a.cycle { |x| puts x } # print, a, b, c, a, b, c,.. forever. a.cycle(2) { |x| puts x } # print, a, b, c, a, b, c.
# File mrbgems/mruby-enum-ext/mrblib/enum.rb, line 664 def cycle(nv = nil, &block) return to_enum(:cycle, nv) unless block n = nil if nv.nil? n = -1 else n = nv.__to_int return nil if n <= 0 end ary = [] each do |*i| ary.push(i) yield(*i) end return nil if ary.empty? while n < 0 || 0 < (n -= 1) ary.each do |i| yield(*i) end end nil end
Return the first element for which value from the block is true. If no
object matches, calls ifnone
and returns its result. Otherwise
returns nil
.
ISO 15.3.2.2.4
# File mrblib/enum.rb, line 75 def detect(ifnone=nil, &block) return to_enum :detect, ifnone unless block self.each{|*val| if block.call(*val) return val.__svalue end } ifnone.call unless ifnone.nil? end
Drops first n elements from enum, and returns rest elements in an array.
a = [1, 2, 3, 4, 5, 0] a.drop(3) #=> [4, 5, 0]
# File mrbgems/mruby-enum-ext/mrblib/enum.rb, line 15 def drop(n) n = n.__to_int raise ArgumentError, "attempt to drop negative size" if n < 0 ary = [] self.each {|*val| n == 0 ? ary << val.__svalue : n -= 1 } ary end
Drops elements up to, but not including, the first element for which the
block returns nil
or false
and returns an array
containing the remaining elements.
If no block is given, an enumerator is returned instead.
a = [1, 2, 3, 4, 5, 0] a.drop_while {|i| i < 3 } #=> [3, 4, 5, 0]
# File mrbgems/mruby-enum-ext/mrblib/enum.rb, line 38 def drop_while(&block) return to_enum :drop_while unless block ary, state = [], false self.each do |*val| state = true if !state and !block.call(*val) ary << val.__svalue if state end ary end
Iterates the given block for each array of consecutive <n> elements.
@return [nil]
@example
(1..10).each_cons(3) {|a| p a} # outputs below [1, 2, 3] [2, 3, 4] [3, 4, 5] [4, 5, 6] [5, 6, 7] [6, 7, 8] [7, 8, 9] [8, 9, 10]
# File mrbgems/mruby-enum-ext/mrblib/enum.rb, line 114 def each_cons(n, &block) n = n.__to_int raise ArgumentError, "invalid size" if n <= 0 return to_enum(:each_cons,n) unless block ary = [] n = n.to_i self.each do |*val| ary.shift if ary.size == n ary << val.__svalue block.call(ary.dup) if ary.size == n end nil end
Iterates the given block for each slice of <n> elements.
@return [nil]
@example
(1..10).each_slice(3) {|a| p a} # outputs below [1, 2, 3] [4, 5, 6] [7, 8, 9] [10]
# File mrbgems/mruby-enum-ext/mrblib/enum.rb, line 142 def each_slice(n, &block) n = n.__to_int raise ArgumentError, "invalid slice size" if n <= 0 return to_enum(:each_slice,n) unless block ary = [] n = n.to_i self.each do |*val| ary << val.__svalue if ary.size == n block.call(ary) ary = [] end end block.call(ary) unless ary.empty? nil end
Call the given block for each element which is yield by each
.
Pass an index to the block which starts at 0 and increase by 1 for each
element.
ISO 15.3.2.2.5
# File mrblib/enum.rb, line 93 def each_with_index(&block) return to_enum :each_with_index unless block i = 0 self.each{|*val| block.call(val.__svalue, i) i += 1 } self end
Iterates the given block for each element with an arbitrary object given, and returns the initially given object.
If no block is given, returns an enumerator.
(1..10).each_with_object([]) { |i, a| a << i*2 } #=> [2, 4, 6, 8, 10, 12, 14, 16, 18, 20]
# File mrbgems/mruby-enum-ext/mrblib/enum.rb, line 607 def each_with_object(obj, &block) return to_enum(:each_with_object, obj) unless block self.each {|*val| block.call(val.__svalue, obj) } obj end
Return an array of all elements which are yield by each
.
ISO 15.3.2.2.6
# File mrblib/enum.rb, line 109 def entries ary = [] self.each{|*val| # __svalue is an internal method ary.push val.__svalue } ary end
# File mrbgems/mruby-enum-ext/mrblib/enum.rb, line 830 def filter_map(&blk) return to_enum(:filter_map) unless blk ary = [] self.each do |x| x = blk.call(x) ary.push x if x end ary end
Call the given block for each element which is yield by each
.
Return an array which contains all elements whose block value was true.
ISO 15.3.2.2.8
# File mrblib/enum.rb, line 131 def find_all(&block) return to_enum :find_all unless block ary = [] self.each{|*val| ary.push(val.__svalue) if block.call(*val) } ary end
Compares each entry in enum with value or passes to
block. Returns the index for the first for which the evaluated
value is non-false. If no object matches, returns nil
If neither block nor argument is given, an enumerator is returned instead.
(1..10).find_index { |i| i % 5 == 0 and i % 7 == 0 } #=> nil (1..100).find_index { |i| i % 5 == 0 and i % 7 == 0 } #=> 34 (1..100).find_index(50) #=> 49
# File mrbgems/mruby-enum-ext/mrblib/enum.rb, line 710 def find_index(val=NONE, &block) return to_enum(:find_index, val) if !block && val == NONE idx = 0 if block self.each do |*e| return idx if block.call(*e) idx += 1 end else self.each do |*e| return idx if e.__svalue == val idx += 1 end end nil end
Returns the first element, or the first n
elements, of the
enumerable. If the enumerable is empty, the first form returns
nil
, and the second form returns an empty array.
# File mrbgems/mruby-enum-ext/mrblib/enum.rb, line 216 def first(*args) case args.length when 0 self.each do |*val| return val.__svalue end return nil when 1 i = args[0].__to_int raise ArgumentError, "attempt to take negative size" if i < 0 ary = [] return ary if i == 0 self.each do |*val| ary << val.__svalue i -= 1 break if i == 0 end ary else raise ArgumentError, "wrong number of arguments (given #{args.length}, expected 0..1)" end end
Returns a new array with the concatenated results of running block once for every element in enum.
If no block is given, an enumerator is returned instead.
[1, 2, 3, 4].flat_map { |e| [e, -e] } #=> [1, -1, 2, -2, 3, -3, 4, -4] [[1, 2], [3, 4]].flat_map { |e| e + [100] } #=> [1, 2, 100, 3, 4, 100]
# File mrbgems/mruby-enum-ext/mrblib/enum.rb, line 281 def flat_map(&block) return to_enum :flat_map unless block ary = [] self.each do |*e| e2 = block.call(*e) if e2.respond_to? :each e2.each {|e3| ary.push(e3) } else ary.push(e2) end end ary end
Call the given block for each element which is yield by each
and which return value was true when invoking === with
pattern
. Return an array with all elements or the respective
block values.
ISO 15.3.2.2.9
# File mrblib/enum.rb, line 149 def grep(pattern, &block) ary = [] self.each{|*val| sv = val.__svalue if pattern === sv ary.push((block)? block.call(*val): sv) end } ary end
Returns a hash, which keys are evaluated result from the block, and values are arrays of elements in enum corresponding to the key.
(1..6).group_by {|i| i%3} #=> {0=>[3, 6], 1=>[1, 4], 2=>[2, 5]}
# File mrbgems/mruby-enum-ext/mrblib/enum.rb, line 171 def group_by(&block) return to_enum :group_by unless block h = {} self.each do |*val| key = block.call(*val) sv = val.__svalue h.key?(key) ? (h[key] << sv) : (h[key] = [sv]) end h end
redefine hash 15.3.1.3.15
# File mrblib/enum.rb, line 344 def hash h = 12347 i = 0 self.each do |e| h = __update_hash(h, i, e.hash) i += 1 end h end
Return true if at least one element which is yield by each
returns a true value by invoking == with obj
. Otherwise return
false.
ISO 15.3.2.2.10
# File mrblib/enum.rb, line 167 def include?(obj) self.each{|*val| return true if val.__svalue == obj } false end
Call the given block for each element which is yield by each
.
Return value is the sum of all block values. Pass to each block the current
sum and the current element.
ISO 15.3.2.2.11
# File mrblib/enum.rb, line 182 def inject(*args, &block) raise ArgumentError, "too many arguments" if args.size > 2 if Symbol === args[-1] sym = args[-1] block = ->(x,y){x.__send__(sym,y)} args.pop end if args.empty? flag = true # no initial argument result = nil else flag = false result = args[0] end self.each{|*val| val = val.__svalue if flag # push first element as initial flag = false result = val else result = block.call(result, val) end } result end
#lazy returns an instance of Enumerator::Lazy. You can use it just like as normal Enumerable object, except these methods act as 'lazy':
- map collect - select find_all - reject - grep - drop - drop_while - take_while - flat_map collect_concat - zip
# File mrbgems/mruby-enum-lazy/mrblib/lazy.rb, line 18 def lazy Enumerator::Lazy.new(self) end
Return the maximum value of all elements yield by each
. If no
block is given <=> will be invoked to define this value. If a block
is given it will be used instead.
ISO 15.3.2.2.13
# File mrblib/enum.rb, line 223 def max(&block) flag = true # 1st element? result = nil self.each{|*val| val = val.__svalue if flag # 1st element result = val flag = false else if block result = val if block.call(val, result) > 0 else result = val if (val <=> result) > 0 end end } result end
Returns the object in enum that gives the maximum value from the given block.
If no block is given, an enumerator is returned instead.
%w[albatross dog horse].max_by {|x| x.length } #=> "albatross"
# File mrbgems/mruby-enum-ext/mrblib/enum.rb, line 309 def max_by(&block) return to_enum :max_by unless block first = true max = nil max_cmp = nil self.each do |*val| if first max = val.__svalue max_cmp = block.call(*val) first = false else if (cmp = block.call(*val)) > max_cmp max = val.__svalue max_cmp = cmp end end end max end
Return the minimum value of all elements yield by each
. If no
block is given <=> will be invoked to define this value. If a block
is given it will be used instead.
ISO 15.3.2.2.14
# File mrblib/enum.rb, line 250 def min(&block) flag = true # 1st element? result = nil self.each{|*val| val = val.__svalue if flag # 1st element result = val flag = false else if block result = val if block.call(val, result) < 0 else result = val if (val <=> result) < 0 end end } result end
Returns the object in enum that gives the minimum value from the given block.
If no block is given, an enumerator is returned instead.
%w[albatross dog horse].min_by {|x| x.length } #=> "dog"
# File mrbgems/mruby-enum-ext/mrblib/enum.rb, line 343 def min_by(&block) return to_enum :min_by unless block first = true min = nil min_cmp = nil self.each do |*val| if first min = val.__svalue min_cmp = block.call(*val) first = false else if (cmp = block.call(*val)) < min_cmp min = val.__svalue min_cmp = cmp end end end min end
Returns two elements array which contains the minimum and the maximum value
in the enumerable. The first form assumes all objects implement
Comparable
; the second uses the block to return a
<=> b.
a = %w(albatross dog horse) a.minmax #=> ["albatross", "horse"] a.minmax { |a, b| a.length <=> b.length } #=> ["dog", "albatross"]
# File mrbgems/mruby-enum-ext/mrblib/enum.rb, line 379 def minmax(&block) max = nil min = nil first = true self.each do |*val| if first val = val.__svalue max = val min = val first = false else val = val.__svalue if block max = val if block.call(val, max) > 0 min = val if block.call(val, min) < 0 else max = val if (val <=> max) > 0 min = val if (val <=> min) < 0 end end end [min, max] end
Returns a two element array containing the objects in enum that correspond to the minimum and maximum values respectively from the given block.
If no block is given, an enumerator is returned instead.
%w(albatross dog horse).minmax_by { |x| x.length } #=> ["dog", "albatross"]
# File mrbgems/mruby-enum-ext/mrblib/enum.rb, line 417 def minmax_by(&block) return to_enum :minmax_by unless block max = nil max_cmp = nil min = nil min_cmp = nil first = true self.each do |*val| if first max = min = val.__svalue max_cmp = min_cmp = block.call(*val) first = false else if (cmp = block.call(*val)) > max_cmp max = val.__svalue max_cmp = cmp end if (cmp = block.call(*val)) < min_cmp min = val.__svalue min_cmp = cmp end end end [min, max] end
Passes each element of the collection to the given block. The method
returns true
if the block never returns true
for
all elements. If the block is not given, none?
will return
true
only if none of the collection members is true.
If a pattern is supplied instead, the method returns whether pattern
=== element
for none of the collection members.
%w(ant bear cat).none? { |word| word.length == 5 } #=> true %w(ant bear cat).none? { |word| word.length >= 4 } #=> false %w{ant bear cat}.none?(/d/) #=> true [1, 3.14, 42].none?(Float) #=> false [].none? #=> true [nil, false].none? #=> true [nil, true].none? #=> false
# File mrbgems/mruby-enum-ext/mrblib/enum.rb, line 466 def none?(pat=NONE, &block) if pat != NONE self.each do |*val| return false if pat === val.__svalue end elsif block self.each do |*val| return false if block.call(*val) end else self.each do |*val| return false if val.__svalue end end true end
Passes each element of the collection to the given block. The method
returns true
if the block returns true
exactly
once. If the block is not given, one?
will return
true
only if exactly one of the collection members is true.
If a pattern is supplied instead, the method returns whether pattern
=== element
for exactly one collection member.
%w(ant bear cat).one? { |word| word.length == 4 } #=> true %w(ant bear cat).one? { |word| word.length > 4 } #=> false %w(ant bear cat).one? { |word| word.length < 4 } #=> false %w{ant bear cat}.one?(/t/) #=> false [nil, true, 99].one? #=> false [nil, true, false].one? #=> true [ nil, true, 99 ].one?(Integer) #=> true [].one? #=> false
# File mrbgems/mruby-enum-ext/mrblib/enum.rb, line 506 def one?(pat=NONE, &block) count = 0 if pat!=NONE self.each do |*val| count += 1 if pat === val.__svalue return false if count > 1 end elsif block self.each do |*val| count += 1 if block.call(*val) return false if count > 1 end else self.each do |*val| count += 1 if val.__svalue return false if count > 1 end end count == 1 ? true : false end
Call the given block for each element which is yield by each
.
Return an array which contains two arrays. The first array contains all
elements whose block value was true. The second array contains all elements
whose block value was false.
ISO 15.3.2.2.16
# File mrblib/enum.rb, line 286 def partition(&block) return to_enum :partition unless block ary_T = [] ary_F = [] self.each{|*val| if block.call(*val) ary_T.push(val.__svalue) else ary_F.push(val.__svalue) end } [ary_T, ary_F] end
Call the given block for each element which is yield by each
.
Return an array which contains only the elements whose block value was
false.
ISO 15.3.2.2.17
# File mrblib/enum.rb, line 308 def reject(&block) return to_enum :reject unless block ary = [] self.each{|*val| ary.push(val.__svalue) unless block.call(*val) } ary end
Builds a temporary array and traverses that array in reverse order.
If no block is given, an enumerator is returned instead.
(1..3).reverse_each { |v| p v } produces: 3 2 1
# File mrbgems/mruby-enum-ext/mrblib/enum.rb, line 632 def reverse_each(&block) return to_enum :reverse_each unless block ary = self.to_a i = ary.size - 1 while i>=0 block.call(ary[i]) i -= 1 end self end
Alias for find_all.
ISO 15.3.2.2.18
Return a sorted array of all elements which are yield by each
.
If no block is given <=> will be invoked on each element to define
the order. Otherwise the given block will be used for sorting.
ISO 15.3.2.2.19
# File mrblib/enum.rb, line 333 def sort(&block) self.map{|*val| val.__svalue}.sort(&block) end
Sorts enum using a set of keys generated by mapping the values in enum through the given block.
If no block is given, an enumerator is returned instead.
# File mrbgems/mruby-enum-ext/mrblib/enum.rb, line 193 def sort_by(&block) return to_enum :sort_by unless block ary = [] orig = [] self.each_with_index{|e, i| orig.push(e) ary.push([block.call(e), i]) } if ary.size > 1 ary.sort! end ary.collect{|e,i| orig[i]} end
Returns first n elements from enum.
a = [1, 2, 3, 4, 5, 0] a.take(3) #=> [1, 2, 3]
# File mrbgems/mruby-enum-ext/mrblib/enum.rb, line 58 def take(n) n = n.__to_int i = n.to_i raise ArgumentError, "attempt to take negative size" if i < 0 ary = [] return ary if i == 0 self.each do |*val| ary << val.__svalue i -= 1 break if i == 0 end ary end
Passes elements to the block until the block returns nil
or
false
, then stops iterating and returns an array of all prior
elements.
If no block is given, an enumerator is returned instead.
a = [1, 2, 3, 4, 5, 0] a.take_while {|i| i < 3 } #=> [1, 2]
# File mrbgems/mruby-enum-ext/mrblib/enum.rb, line 85 def take_while(&block) return to_enum :take_while unless block ary = [] self.each do |*val| return ary unless block.call(*val) ary << val.__svalue end ary end
Tallys the collection. Returns a hash where the keys are the elements and the values are numbers of elements in the collection that correspond to the key.
["a", "b", "c", "b"].tally #=> {"a"=>1, "b"=>2, "c"=>1}
# File mrbgems/mruby-enum-ext/mrblib/enum.rb, line 852 def tally hash = {} self.each do |x| hash[x] = (hash[x]||0)+1 end hash end
Returns the result of interpreting enum as a list of [key,
value]
pairs.
%i[hello world].each_with_index.to_h # => {:hello => 0, :world => 1}
# File mrbgems/mruby-enum-ext/mrblib/enum.rb, line 794 def to_h(&blk) h = {} if blk self.each do |v| v = blk.call(v) raise TypeError, "wrong element type #{v.class} (expected Array)" unless v.is_a? Array raise ArgumentError, "element has wrong array length (expected 2, was #{v.size})" if v.size != 2 h[v[0]] = v[1] end else self.each do |*v| v = v.__svalue raise TypeError, "wrong element type #{v.class} (expected Array)" unless v.is_a? Array raise ArgumentError, "element has wrong array length (expected 2, was #{v.size})" if v.size != 2 h[v[0]] = v[1] end end h end
# File mrbgems/mruby-enum-ext/mrblib/enum.rb, line 814 def uniq(&block) hash = {} if block self.each do|*v| v = v.__svalue hash[block.call(v)] ||= v end else self.each do|*v| v = v.__svalue hash[v] ||= v end end hash.values end
Takes one element from enum and merges corresponding elements from
each args. This generates a sequence of n-element
arrays, where n is one more than the count of arguments. The
length of the resulting sequence will be enum#size
. If the
size of any argument is less than enum#size
, nil
values are supplied. If a block is given, it is invoked for each output
array, otherwise an array of arrays is returned.
a = [ 4, 5, 6 ] b = [ 7, 8, 9 ] a.zip(b) #=> [[4, 7], [5, 8], [6, 9]] [1, 2, 3].zip(a, b) #=> [[1, 4, 7], [2, 5, 8], [3, 6, 9]] [1, 2].zip(a, b) #=> [[1, 4, 7], [2, 5, 8]] a.zip([1, 2], [8]) #=> [[4, 1, 8], [5, 2, nil], [6, nil, nil]] c = [] a.zip(b) { |x, y| c << x + y } #=> nil c #=> [11, 13, 15]
# File mrbgems/mruby-enum-ext/mrblib/enum.rb, line 755 def zip(*arg, &block) result = block ? nil : [] arg = arg.map do |a| unless a.respond_to?(:to_a) raise TypeError, "wrong argument type #{a.class} (must respond to :to_a)" end a.to_a end i = 0 self.each do |*val| a = [] a.push(val.__svalue) idx = 0 while idx < arg.size a.push(arg[idx][i]) idx += 1 end i += 1 if result.nil? block.call(a) else result.push(a) end end result end