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