core/enumerable.rbs in rbs-2.0.0 vs core/enumerable.rbs in rbs-2.1.0

- old
+ new

@@ -1,426 +1,2365 @@ -# 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. -module Enumerable[unchecked out Elem]: _Each[Elem] - # Passes each element of the collection to the given block. The method - # returns `true` if the block never returns `false` or `nil` . If the - # block is not given, Ruby adds an implicit block of `{ |obj| obj }` which - # will cause [all?](Enumerable.downloaded.ruby_doc#method-i-all-3F) to - # return `true` when none of the collection members are `false` or `nil` . +# <!-- rdoc-file=enum.c --> +# ## What's Here +# +# Module Enumerable provides methods that are useful to a collection class for: +# * [Querying](#module-Enumerable-label-Methods+for+Querying) +# * [Fetching](#module-Enumerable-label-Methods+for+Fetching) +# * [Searching](#module-Enumerable-label-Methods+for+Searching) +# * [Sorting](#module-Enumerable-label-Methods+for+Sorting) +# * [Iterating](#module-Enumerable-label-Methods+for+Iterating) +# * [And more....](#module-Enumerable-label-Other+Methods) +# +# +# ### Methods for Querying +# +# These methods return information about the Enumerable other than the elements +# themselves: +# +# #include?, #member? +# : Returns `true` if self == object, `false` otherwise. +# #all? +# : Returns `true` if all elements meet a specified criterion; `false` +# otherwise. +# #any? +# : Returns `true` if any element meets a specified criterion; `false` +# otherwise. +# #none? +# : Returns `true` if no element meets a specified criterion; `false` +# otherwise. +# #one? +# : Returns `true` if exactly one element meets a specified criterion; `false` +# otherwise. +# #count +# : Returns the count of elements, based on an argument or block criterion, if +# given. +# #tally +# : Returns a new Hash containing the counts of occurrences of each element. +# +# +# ### Methods for Fetching +# +# These methods return entries from the Enumerable, without modifying it: +# +# *Leading, trailing, or all elements*: +# #entries, #to_a +# : Returns all elements. +# #first +# : Returns the first element or leading elements. +# #take +# : Returns a specified number of leading elements. +# #drop +# : Returns a specified number of trailing elements. +# #take_while +# : Returns leading elements as specified by the given block. +# #drop_while +# : Returns trailing elements as specified by the given block. +# +# +# *Minimum and maximum value elements*: +# #min +# : Returns the elements whose values are smallest among the elements, as +# determined by `<=>` or a given block. +# #max +# : Returns the elements whose values are largest among the elements, as +# determined by `<=>` or a given block. +# #minmax +# : Returns a 2-element Array containing the smallest and largest elements. +# #min_by +# : Returns the smallest element, as determined by the given block. +# #max_by +# : Returns the largest element, as determined by the given block. +# #minmax_by +# : Returns the smallest and largest elements, as determined by the given +# block. +# +# +# *Groups, slices, and partitions*: +# #group_by +# : Returns a Hash that partitions the elements into groups. +# #partition +# : Returns elements partitioned into two new Arrays, as determined by the +# given block. +# #slice_after +# : Returns a new Enumerator whose entries are a partition of `self`, based +# either on a given `object` or a given block. +# #slice_before +# : Returns a new Enumerator whose entries are a partition of `self`, based +# either on a given `object` or a given block. +# #slice_when +# : Returns a new Enumerator whose entries are a partition of `self` based on +# the given block. +# #chunk +# : Returns elements organized into chunks as specified by the given block. +# #chunk_while +# : Returns elements organized into chunks as specified by the given block. +# +# +# ### Methods for Searching and Filtering +# +# These methods return elements that meet a specified criterion. +# +# #find, #detect +# : Returns an element selected by the block. +# #find_all, #filter, #select +# : Returns elements selected by the block. +# #find_index +# : Returns the index of an element selected by a given object or block. +# #reject +# : Returns elements not rejected by the block. +# #uniq +# : Returns elements that are not duplicates. +# +# +# ### Methods for Sorting +# +# These methods return elements in sorted order. +# +# #sort +# : Returns the elements, sorted by `<=>` or the given block. +# #sort_by +# : Returns the elements, sorted by the given block. +# +# +# ### Methods for Iterating +# +# #each_entry +# : Calls the block with each successive element (slightly different from +# #each). +# #each_with_index +# : Calls the block with each successive element and its index. +# #each_with_object +# : Calls the block with each successive element and a given object. +# #each_slice +# : Calls the block with successive non-overlapping slices. +# #each_cons +# : Calls the block with successive overlapping slices. (different from +# #each_slice). +# #reverse_each +# : Calls the block with each successive element, in reverse order. +# +# +# ### Other Methods +# +# #map, #collect +# : Returns objects returned by the block. +# #filter_map +# : Returns truthy objects returned by the block. +# #flat_map, #collect_concat +# : Returns flattened objects returned by the block. +# #grep +# : Returns elements selected by a given object or objects returned by a given +# block. +# #grep_v +# : Returns elements selected by a given object or objects returned by a given +# block. +# #reduce, #inject +# : Returns the object formed by combining all elements. +# #sum +# : Returns the sum of the elements, using method +++. +# #zip +# : Combines each element with elements from other enumerables; returns the +# n-tuples or calls the block with each. +# #cycle +# : Calls the block with each element, cycling repeatedly. +# +# +# ## Usage +# +# To use module Enumerable in a collection class: +# +# * Include it: +# +# include Enumerable +# +# * Implement method `#each` which must yield successive elements of the +# collection. The method will be called by almost any Enumerable method. +# +# +# Example: +# +# class Foo +# include Enumerable +# def each +# yield 1 +# yield 1, 2 +# yield +# end +# end +# Foo.new.each_entry{ |element| p element } +# +# Output: +# +# 1 +# [1, 2] +# nil +# +# ## Enumerable in Ruby Core Classes +# Some Ruby classes include Enumerable: +# * Array +# * Dir +# * Hash +# * IO +# * Range +# * Set +# * Struct +# +# Virtually all methods in Enumerable call method `#each` in the including +# class: +# * `Hash#each` yields the next key-value pair as a 2-element Array. +# * `Struct#each` yields the next name-value pair as a 2-element Array. +# * For the other classes above, `#each` yields the next object from the +# collection. +# +# +# ## About the Examples +# The example code snippets for the Enumerable methods: +# * Always show the use of one or more Array-like classes (often Array +# itself). +# * Sometimes show the use of a Hash-like class. For some methods, though, the +# usage would not make sense, and so it is not shown. Example: #tally would +# find exactly one of each Hash entry. +# +module Enumerable[unchecked out Elem] : _Each[Elem] + # <!-- + # rdoc-file=enum.c + # - all? -> true or false + # - all?(pattern) -> true or false + # - all? {|element| ... } -> true or false + # --> + # Returns whether every element meets a given criterion. # - # If instead a pattern is supplied, the method returns whether `pattern - # === element` for every collection member. + # With no argument and no block, returns whether every element is truthy: # - # %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 - # [].all? #=> true + # (1..4).all? # => true + # %w[a b c d].all? # => true + # [1, 2, nil].all? # => false + # ['a','b', false].all? # => false + # [].all? # => true + # + # With argument `pattern` and no block, returns whether for each element + # `element`, `pattern === element`: + # + # (1..4).all?(Integer) # => true + # (1..4).all?(Numeric) # => true + # (1..4).all?(Float) # => false + # %w[bar baz bat bam].all?(/ba/) # => true + # %w[bar baz bat bam].all?(/bar/) # => false + # %w[bar baz bat bam].all?('ba') # => false + # {foo: 0, bar: 1, baz: 2}.all?(Array) # => true + # {foo: 0, bar: 1, baz: 2}.all?(Hash) # => false + # [].all?(Integer) # => true + # + # With a block given, returns whether the block returns a truthy value for every + # element: + # + # (1..4).all? {|element| element < 5 } # => true + # (1..4).all? {|element| element < 4 } # => false + # {foo: 0, bar: 1, baz: 2}.all? {|key, value| value < 3 } # => true + # {foo: 0, bar: 1, baz: 2}.all? {|key, value| value < 2 } # => false + # + # Related: #any?, #none? #one?. + # def all?: () -> bool | () { (Elem) -> boolish } -> bool - # Passes each element of the collection to the given block. The method - # returns `true` if the block ever returns a value other than `false` or - # `nil` . If the block is not given, Ruby adds an implicit block of `{ - # |obj| obj }` that will cause - # [any?](Enumerable.downloaded.ruby_doc#method-i-any-3F) to return `true` - # if at least one of the collection members is not `false` or `nil` . + # <!-- + # rdoc-file=enum.c + # - any? -> true or false + # - any?(pattern) -> true or false + # - any? {|element| ... } -> true or false + # --> + # Returns whether any element meets a given criterion. # - # If instead a pattern is supplied, the method returns whether `pattern - # === element` for any collection member. + # With no argument and no block, returns whether any element is truthy: # - # ```ruby - # %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 - # ``` - def `any?`: () -> bool - | () { (Elem) -> boolish } -> bool + # (1..4).any? # => true + # %w[a b c d].any? # => true + # [1, false, nil].any? # => true + # [].any? # => false + # + # With argument `pattern` and no block, returns whether for any element + # `element`, `pattern === element`: + # + # [nil, false, 0].any?(Integer) # => true + # [nil, false, 0].any?(Numeric) # => true + # [nil, false, 0].any?(Float) # => false + # %w[bar baz bat bam].any?(/m/) # => true + # %w[bar baz bat bam].any?(/foo/) # => false + # %w[bar baz bat bam].any?('ba') # => false + # {foo: 0, bar: 1, baz: 2}.any?(Array) # => true + # {foo: 0, bar: 1, baz: 2}.any?(Hash) # => false + # [].any?(Integer) # => false + # + # With a block given, returns whether the block returns a truthy value for any + # element: + # + # (1..4).any? {|element| element < 2 } # => true + # (1..4).any? {|element| element < 1 } # => false + # {foo: 0, bar: 1, baz: 2}.any? {|key, value| value < 1 } # => true + # {foo: 0, bar: 1, baz: 2}.any? {|key, value| value < 0 } # => false + # + # Related: #all?, #none?, #one?. + # + def any?: () -> bool + | () { (Elem) -> boolish } -> bool + # <!-- + # rdoc-file=enum.c + # - map {|element| ... } -> array + # - map -> enumerator + # --> + # Returns an array of objects returned by the block. + # + # With a block given, calls the block with successive elements; returns an array + # of the objects returned by the block: + # + # (0..4).map {|i| i*i } # => [0, 1, 4, 9, 16] + # {foo: 0, bar: 1, baz: 2}.map {|key, value| value*2} # => [0, 2, 4] + # + # With no block given, returns an Enumerator. + # def collect: [U] () { (Elem arg0) -> U } -> ::Array[U] | () -> ::Enumerator[Elem, ::Array[untyped]] + # <!-- rdoc-file=enum.c --> + # Returns an array of flattened objects returned by the block. + # + # With a block given, calls the block with successive elements; returns a + # flattened array of objects returned by the block: + # + # [0, 1, 2, 3].flat_map {|element| -element } # => [0, -1, -2, -3] + # [0, 1, 2, 3].flat_map {|element| [element, -element] } # => [0, 0, 1, -1, 2, -2, 3, -3] + # [[0, 1], [2, 3]].flat_map {|e| e + [100] } # => [0, 1, 100, 2, 3, 100] + # {foo: 0, bar: 1, baz: 2}.flat_map {|key, value| [key, value] } # => [:foo, 0, :bar, 1, :baz, 2] + # + # With no block given, returns an Enumerator. + # + # Alias: #collect_concat. + # def collect_concat: [U] () { (Elem) -> (::Array[U] | U) } -> ::Array[U] | () -> ::Enumerator[Elem, ::Array[untyped]] - # 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. + # <!-- + # rdoc-file=enum.c + # - compact -> array + # --> + # Returns an array of all non-`nil` elements: # - # ```ruby - # ary = [1, 2, 4, 2] - # ary.count #=> 4 - # ary.count(2) #=> 2 - # ary.count{ |x| x%2==0 } #=> 3 - # ``` + # a = [nil, 0, nil, 'a', false, nil, false, nil, 'a', nil, 0, nil] + # a.compact # => [0, "a", false, false, "a", 0] + # + def compact: () -> Array[Elem] + + # <!-- + # rdoc-file=enum.c + # - count -> integer + # - count(object) -> integer + # - count {|element| ... } -> integer + # --> + # Returns the count of elements, based on an argument or block criterion, if + # given. + # + # With no argument and no block given, returns the number of elements: + # + # [0, 1, 2].count # => 3 + # {foo: 0, bar: 1, baz: 2}.count # => 3 + # + # With argument `object` given, returns the number of elements that are `==` to + # `object`: + # + # [0, 1, 2, 1].count(1) # => 2 + # + # With a block given, calls the block with each element and returns the number + # of elements for which the block returns a truthy value: + # + # [0, 1, 2, 3].count {|element| element < 2} # => 2 + # {foo: 0, bar: 1, baz: 2}.count {|key, value| value < 2} # => 2 + # def count: () -> Integer | (Elem) -> Integer | () { (Elem) -> boolish } -> Integer + # <!-- + # rdoc-file=enum.c + # - cycle(n = nil) {|element| ...} -> nil + # - cycle(n = nil) -> enumerator + # --> + # When called with positive integer argument `n` and a block, calls the block + # with each element, then does so again, until it has done so `n` times; returns + # `nil`: + # + # a = [] + # (1..4).cycle(3) {|element| a.push(element) } # => nil + # a # => [1, 2, 3, 4, 1, 2, 3, 4, 1, 2, 3, 4] + # a = [] + # ('a'..'d').cycle(2) {|element| a.push(element) } + # a # => ["a", "b", "c", "d", "a", "b", "c", "d"] + # a = [] + # {foo: 0, bar: 1, baz: 2}.cycle(2) {|element| a.push(element) } + # a # => [[:foo, 0], [:bar, 1], [:baz, 2], [:foo, 0], [:bar, 1], [:baz, 2]] + # + # If count is zero or negative, does not call the block. + # + # When called with a block and `n` is `nil`, cycles forever. + # + # When no block is given, returns an Enumerator. + # def cycle: (?Integer n) { (Elem arg0) -> untyped } -> NilClass | (?Integer n) -> ::Enumerator[Elem, NilClass] + # <!-- rdoc-file=enum.c --> + # Returns the first element for which the block returns a truthy value. + # + # With a block given, calls the block with successive elements of the + # collection; returns the first element for which the block returns a truthy + # value: + # + # (0..9).find {|element| element > 2} # => 3 + # + # If no such element is found, calls `if_none_proc` and returns its return + # value. + # + # (0..9).find(proc {false}) {|element| element > 12} # => false + # {foo: 0, bar: 1, baz: 2}.find {|key, value| key.start_with?('b') } # => [:bar, 1] + # {foo: 0, bar: 1, baz: 2}.find(proc {[]}) {|key, value| key.start_with?('c') } # => [] + # + # With no block given, returns an Enumerator. + # def detect: (?Proc ifnone) { (Elem) -> boolish } -> Elem? | (?Proc ifnone) -> ::Enumerator[Elem, Elem?] + # <!-- + # rdoc-file=enum.c + # - drop(n) -> array + # --> + # For positive integer `n`, returns an array containing all but the first `n` + # elements: + # + # r = (1..4) + # r.drop(3) # => [4] + # r.drop(2) # => [3, 4] + # r.drop(1) # => [2, 3, 4] + # r.drop(0) # => [1, 2, 3, 4] + # r.drop(50) # => [] + # + # h = {foo: 0, bar: 1, baz: 2, bat: 3} + # h.drop(2) # => [[:baz, 2], [:bat, 3]] + # def drop: (Integer n) -> ::Array[Elem] + # <!-- + # rdoc-file=enum.c + # - drop_while {|element| ... } -> array + # - drop_while -> enumerator + # --> + # Calls the block with successive elements as long as the block returns a truthy + # value; returns an array of all elements after that point: + # + # (1..4).drop_while{|i| i < 3 } # => [3, 4] + # h = {foo: 0, bar: 1, baz: 2} + # a = h.drop_while{|element| key, value = *element; value < 2 } + # a # => [[:baz, 2]] + # + # With no block given, returns an Enumerator. + # def drop_while: () { (Elem) -> boolish } -> ::Array[Elem] | () -> ::Enumerator[Elem, ::Array[Elem]] - def each_cons: (Integer n) { (::Array[Elem] arg0) -> untyped } -> NilClass - | (Integer n) -> ::Enumerator[::Array[Elem], NilClass] + # <!-- + # rdoc-file=enum.c + # - each_cons(n) { ... } -> self + # - each_cons(n) -> enumerator + # --> + # Calls the block with each successive overlapped `n`-tuple of elements; returns + # `self`: + # + # a = [] + # (1..5).each_cons(3) {|element| a.push(element) } + # a # => [[1, 2, 3], [2, 3, 4], [3, 4, 5]] + # + # a = [] + # h = {foo: 0, bar: 1, baz: 2, bam: 3} + # h.each_cons(2) {|element| a.push(element) } + # a # => [[[:foo, 0], [:bar, 1]], [[:bar, 1], [:baz, 2]], [[:baz, 2], [:bam, 3]]] + # + # With no block given, returns an Enumerator. + # + def each_cons: (Integer n) { (::Array[Elem]) -> void } -> self + | (Integer n) -> ::Enumerator[::Array[Elem], self] + # <!-- + # rdoc-file=enum.c + # - each_with_index(*args) {|element, i| ..... } -> self + # - each_with_index(*args) -> enumerator + # --> + # With a block given, calls the block with each element and its index; returns + # `self`: + # + # h = {} + # (1..4).each_with_index {|element, i| h[element] = i } # => 1..4 + # h # => {1=>0, 2=>1, 3=>2, 4=>3} + # + # h = {} + # %w[a b c d].each_with_index {|element, i| h[element] = i } + # # => ["a", "b", "c", "d"] + # h # => {"a"=>0, "b"=>1, "c"=>2, "d"=>3} + # + # a = [] + # h = {foo: 0, bar: 1, baz: 2} + # h.each_with_index {|element, i| a.push([i, element]) } + # # => {:foo=>0, :bar=>1, :baz=>2} + # a # => [[0, [:foo, 0]], [1, [:bar, 1]], [2, [:baz, 2]]] + # + # With no block given, returns an Enumerator. + # def each_with_index: () { (Elem, Integer index) -> untyped } -> self | () -> ::Enumerator[[ Elem, Integer ], self] + # <!-- + # rdoc-file=enum.c + # - each_with_object(object) { |(*args), memo_object| ... } -> object + # - each_with_object(object) -> enumerator + # --> + # Calls the block once for each element, passing both the element and the given + # object: + # + # (1..4).each_with_object([]) {|i, a| a.push(i**2) } # => [1, 4, 9, 16] + # h.each_with_object({}) {|element, h| k, v = *element; h[v] = k } + # # => {0=>:foo, 1=>:bar, 2=>:baz} + # + # With no block given, returns an Enumerator. + # def each_with_object: [U] (U obj) { (Elem, U obj) -> untyped } -> U | [U] (U obj) -> ::Enumerator[[ Elem, U ], U] - # Returns an array containing the items in *enum* . + # <!-- rdoc-file=enum.c --> + # Returns an array containing the items in `self`: # - # ```ruby - # (1..7).to_a #=> [1, 2, 3, 4, 5, 6, 7] - # { 'a'=>1, 'b'=>2, 'c'=>3 }.to_a #=> [["a", 1], ["b", 2], ["c", 3]] + # (0..4).to_a # => [0, 1, 2, 3, 4] # - # require 'prime' - # Prime.entries 10 #=> [2, 3, 5, 7] - # ``` + # Enumerable#entries is an alias for Enumerable#to_a. + # def entries: () -> ::Array[Elem] + # <!-- + # rdoc-file=enum.c + # - select {|element| ... } -> array + # - select -> enumerator + # --> + # Returns an array containing elements selected by the block. + # + # With a block given, calls the block with successive elements; returns an array + # of those elements for which the block returns a truthy value: + # + # (0..9).select {|element| element % 3 == 0 } # => [0, 3, 6, 9] + # a = {foo: 0, bar: 1, baz: 2}.select {|key, value| key.start_with?('b') } + # a # => {:bar=>1, :baz=>2} + # + # With no block given, returns an Enumerator. + # + # Related: #reject. + # def find_all: () { (Elem) -> boolish } -> ::Array[Elem] | () -> ::Enumerator[Elem, ::Array[Elem]] + # <!-- rdoc-file=enum.c --> + # Returns an array containing elements selected by the block. + # + # With a block given, calls the block with successive elements; returns an array + # of those elements for which the block returns a truthy value: + # + # (0..9).select {|element| element % 3 == 0 } # => [0, 3, 6, 9] + # a = {foo: 0, bar: 1, baz: 2}.select {|key, value| key.start_with?('b') } + # a # => {:bar=>1, :baz=>2} + # + # With no block given, returns an Enumerator. + # + # Related: #reject. + # alias select find_all + + # <!-- rdoc-file=enum.c --> + # Returns an array containing elements selected by the block. + # + # With a block given, calls the block with successive elements; returns an array + # of those elements for which the block returns a truthy value: + # + # (0..9).select {|element| element % 3 == 0 } # => [0, 3, 6, 9] + # a = {foo: 0, bar: 1, baz: 2}.select {|key, value| key.start_with?('b') } + # a # => {:bar=>1, :baz=>2} + # + # With no block given, returns an Enumerator. + # + # Related: #reject. + # alias filter find_all + # <!-- + # rdoc-file=enum.c + # - find_index(object) -> integer or nil + # - find_index {|element| ... } -> integer or nil + # - find_index -> enumerator + # --> + # Returns the index of the first element that meets a specified criterion, or + # `nil` if no such element is found. + # + # With argument `object` given, returns the index of the first element that is + # `==` `object`: + # + # ['a', 'b', 'c', 'b'].find_index('b') # => 1 + # + # With a block given, calls the block with successive elements; returns the + # first element for which the block returns a truthy value: + # + # ['a', 'b', 'c', 'b'].find_index {|element| element.start_with?('b') } # => 1 + # {foo: 0, bar: 1, baz: 2}.find_index {|key, value| value > 1 } # => 2 + # + # With no argument and no block given, returns an Enumerator. + # def find_index: (untyped value) -> Integer? | () { (Elem) -> boolish } -> Integer? | () -> ::Enumerator[Elem, Integer?] - # 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. + # <!-- + # rdoc-file=enum.c + # - first -> element or nil + # - first(n) -> array + # --> + # Returns the first element or elements. # - # ```ruby - # %w[foo bar baz].first #=> "foo" - # %w[foo bar baz].first(2) #=> ["foo", "bar"] - # %w[foo bar baz].first(10) #=> ["foo", "bar", "baz"] - # [].first #=> nil - # [].first(10) #=> [] - # ``` + # With no argument, returns the first element, or `nil` if there is none: + # + # (1..4).first # => 1 + # %w[a b c].first # => "a" + # {foo: 1, bar: 1, baz: 2}.first # => [:foo, 1] + # [].first # => nil + # + # With integer argument `n`, returns an array containing the first `n` elements + # that exist: + # + # (1..4).first(2) # => [1, 2] + # %w[a b c d].first(3) # => ["a", "b", "c"] + # %w[a b c d].first(50) # => ["a", "b", "c", "d"] + # {foo: 1, bar: 1, baz: 2}.first(2) # => [[:foo, 1], [:bar, 1]] + # [].first(2) # => [] + # def first: () -> Elem? | (_ToInt n) -> ::Array[Elem] + # <!-- + # rdoc-file=enum.c + # - grep(pattern) -> array + # - grep(pattern) {|element| ... } -> array + # --> + # Returns an array of objects based elements of `self` that match the given + # pattern. + # + # With no block given, returns an array containing each element for which + # `pattern === element` is `true`: + # + # a = ['foo', 'bar', 'car', 'moo'] + # a.grep(/ar/) # => ["bar", "car"] + # (1..10).grep(3..8) # => [3, 4, 5, 6, 7, 8] + # ['a', 'b', 0, 1].grep(Integer) # => [0, 1] + # + # With a block given, calls the block with each matching element and returns an + # array containing each object returned by the block: + # + # a = ['foo', 'bar', 'car', 'moo'] + # a.grep(/ar/) {|element| element.upcase } # => ["BAR", "CAR"] + # + # Related: #grep_v. + # def grep: (untyped arg0) -> ::Array[Elem] | [U] (untyped arg0) { (Elem arg0) -> U } -> ::Array[U] + # <!-- + # rdoc-file=enum.c + # - grep_v(pattern) -> array + # - grep_v(pattern) {|element| ... } -> array + # --> + # Returns an array of objects based on elements of `self` that *don't* match the + # given pattern. + # + # With no block given, returns an array containing each element for which + # `pattern === element` is `false`: + # + # a = ['foo', 'bar', 'car', 'moo'] + # a.grep_v(/ar/) # => ["foo", "moo"] + # (1..10).grep_v(3..8) # => [1, 2, 9, 10] + # ['a', 'b', 0, 1].grep_v(Integer) # => ["a", "b"] + # + # With a block given, calls the block with each non-matching element and returns + # an array containing each object returned by the block: + # + # a = ['foo', 'bar', 'car', 'moo'] + # a.grep_v(/ar/) {|element| element.upcase } # => ["FOO", "MOO"] + # + # Related: #grep. + # def grep_v: (untyped) -> ::Array[Elem] | [U] (untyped) { (Elem) -> U } -> ::Array[U] + # <!-- + # rdoc-file=enum.c + # - group_by {|element| ... } -> hash + # - group_by -> enumerator + # --> + # With a block given returns a hash: + # + # * Each key is a return value from the block. + # * Each value is an array of those elements for which the block returned that + # key. + # + # + # Examples: + # + # g = (1..6).group_by {|i| i%3 } + # g # => {1=>[1, 4], 2=>[2, 5], 0=>[3, 6]} + # h = {foo: 0, bar: 1, baz: 0, bat: 1} + # g = h.group_by {|key, value| value } + # g # => {0=>[[:foo, 0], [:baz, 0]], 1=>[[:bar, 1], [:bat, 1]]} + # + # With no block given, returns an Enumerator. + # def group_by: [U] () { (Elem arg0) -> U } -> ::Hash[U, ::Array[Elem]] | () -> ::Enumerator[Elem, ::Array[Elem]] - def `include?`: (Elem arg0) -> bool + # <!-- rdoc-file=enum.c --> + # Returns whether for any element `object == element`: + # + # (1..4).include?(2) # => true + # (1..4).include?(5) # => false + # (1..4).include?('2') # => false + # %w[a b c d].include?('b') # => true + # %w[a b c d].include?('2') # => false + # {foo: 0, bar: 1, baz: 2}.include?(:foo) # => true + # {foo: 0, bar: 1, baz: 2}.include?('foo') # => false + # {foo: 0, bar: 1, baz: 2}.include?(0) # => false + # + # Enumerable#member? is an alias for Enumerable#include?. + # + def include?: (Elem arg0) -> bool + # <!-- + # rdoc-file=enum.c + # - inject(symbol) -> object + # - inject(initial_operand, symbol) -> object + # - inject {|memo, operand| ... } -> object + # - inject(initial_operand) {|memo, operand| ... } -> object + # --> + # Returns an object formed from operands via either: + # + # * A method named by `symbol`. + # * A block to which each operand is passed. + # + # + # With method-name argument `symbol`, combines operands using the method: + # + # # Sum, without initial_operand. + # (1..4).inject(:+) # => 10 + # # Sum, with initial_operand. + # (1..4).inject(10, :+) # => 20 + # + # With a block, passes each operand to the block: + # + # # Sum of squares, without initial_operand. + # (1..4).inject {|sum, n| sum + n*n } # => 30 + # # Sum of squares, with initial_operand. + # (1..4).inject(2) {|sum, n| sum + n*n } # => 32 + # + # **Operands** + # + # If argument `initial_operand` is not given, the operands for `inject` are + # simply the elements of `self`. Example calls and their operands: + # + # `(1..4).inject(:+)` + # : `[1, 2, 3, 4]`. + # + # `(1...4).inject(:+)` + # : `[1, 2, 3]`. + # + # `('a'..'d').inject(:+)` + # : `['a', 'b', 'c', 'd']`. + # + # `('a'...'d').inject(:+)` + # : `['a', 'b', 'c']`. + # + # + # + # Examples with first operand (which is `self.first`) of various types: + # + # # Integer. + # (1..4).inject(:+) # => 10 + # # Float. + # [1.0, 2, 3, 4].inject(:+) # => 10.0 + # # Character. + # ('a'..'d').inject(:+) # => "abcd" + # # Complex. + # [Complex(1, 2), 3, 4].inject(:+) # => (8+2i) + # + # If argument `initial_operand` is given, the operands for `inject` are that + # value plus the elements of `self`. Example calls their operands: + # + # `(1..4).inject(10, :+)` + # : `[10, 1, 2, 3, 4]`. + # + # `(1...4).inject(10, :+)` + # : `[10, 1, 2, 3]`. + # + # `('a'..'d').inject('e', :+)` + # : `['e', 'a', 'b', 'c', 'd']`. + # + # `('a'...'d').inject('e', :+)` + # : `['e', 'a', 'b', 'c']`. + # + # + # + # Examples with `initial_operand` of various types: + # + # # Integer. + # (1..4).inject(2, :+) # => 12 + # # Float. + # (1..4).inject(2.0, :+) # => 12.0 + # # String. + # ('a'..'d').inject('foo', :+) # => "fooabcd" + # # Array. + # %w[a b c].inject(['x'], :push) # => ["x", "a", "b", "c"] + # # Complex. + # (1..4).inject(Complex(2, 2), :+) # => (12+2i) + # + # **Combination by Given \Method** + # + # If the method-name argument `symbol` is given, the operands are combined by + # that method: + # + # * The first and second operands are combined. + # * That result is combined with the third operand. + # * That result is combined with the fourth operand. + # * And so on. + # + # + # The return value from `inject` is the result of the last combination. + # + # This call to `inject` computes the sum of the operands: + # + # (1..4).inject(:+) # => 10 + # + # Examples with various methods: + # + # # Integer addition. + # (1..4).inject(:+) # => 10 + # # Integer multiplication. + # (1..4).inject(:*) # => 24 + # # Character range concatenation. + # ('a'..'d').inject('', :+) # => "abcd" + # # String array concatenation. + # %w[foo bar baz].inject('', :+) # => "foobarbaz" + # # Hash update. + # h = [{foo: 0, bar: 1}, {baz: 2}, {bat: 3}].inject(:update) + # h # => {:foo=>0, :bar=>1, :baz=>2, :bat=>3} + # # Hash conversion to nested arrays. + # h = {foo: 0, bar: 1}.inject([], :push) + # h # => [[:foo, 0], [:bar, 1]] + # + # **Combination by Given Block** + # + # If a block is given, the operands are passed to the block: + # + # * The first call passes the first and second operands. + # * The second call passes the result of the first call, along with the third + # operand. + # * The third call passes the result of the second call, along with the fourth + # operand. + # * And so on. + # + # + # The return value from `inject` is the return value from the last block call. + # + # This call to `inject` gives a block that writes the memo and element, and also + # sums the elements: + # + # (1..4).inject do |memo, element| + # p "Memo: #{memo}; element: #{element}" + # memo + element + # end # => 10 + # + # Output: + # + # "Memo: 1; element: 2" + # "Memo: 3; element: 3" + # "Memo: 6; element: 4" + # + # Enumerable#reduce is an alias for Enumerable#inject. + # def inject: (untyped init, Symbol method) -> untyped | (Symbol method) -> untyped | [A] (A initial) { (A, Elem) -> A } -> A | () { (Elem, Elem) -> Elem } -> Elem - # Returns the object in *enum* with the maximum value. The first form - # assumes all objects implement `Comparable` ; the second uses the block - # to return *a \<=\> b* . + # <!-- + # rdoc-file=enum.c + # - max -> element + # - max(n) -> array + # - max {|a, b| ... } -> element + # - max(n) {|a, b| ... } -> array + # --> + # Returns the element with the maximum element according to a given criterion. + # The ordering of equal elements is indeterminate and may be unstable. # - # ```ruby - # a = %w(albatross dog horse) - # a.max #=> "horse" - # a.max { |a, b| a.length <=> b.length } #=> "albatross" - # ``` + # With no argument and no block, returns the maximum element, using the + # elements' own method `<=>` for comparison: # - # If the `n` argument is given, maximum `n` elements are returned as an - # array, sorted in descending order. + # (1..4).max # => 4 + # (-4..-1).max # => -1 + # %w[d c b a].max # => "d" + # {foo: 0, bar: 1, baz: 2}.max # => [:foo, 0] + # [].max # => nil # - # ```ruby - # a = %w[albatross dog horse] - # a.max(2) #=> ["horse", "dog"] - # a.max(2) {|a, b| a.length <=> b.length } #=> ["albatross", "horse"] - # [5, 1, 3, 4, 2].max(3) #=> [5, 4, 3] - # ``` + # With positive integer argument `n` given, and no block, returns an array + # containing the first `n` maximum elements that exist: + # + # (1..4).max(2) # => [4, 3] + # (-4..-1).max(2) # => [-1, -2] + # %w[d c b a].max(2) # => ["d", "c"] + # {foo: 0, bar: 1, baz: 2}.max(2) # => [[:foo, 0], [:baz, 2]] + # [].max(2) # => [] + # + # With a block given, the block determines the maximum elements. The block is + # called with two elements `a` and `b`, and must return: + # + # * A negative integer if `a < b`. + # * Zero if `a == b`. + # * A positive integer if `a > b`. + # + # + # With a block given and no argument, returns the maximum element as determined + # by the block: + # + # %w[xxx x xxxx xx].max {|a, b| a.size <=> b.size } # => "xxxx" + # h = {foo: 0, bar: 1, baz: 2} + # h.max {|pair1, pair2| pair1[1] <=> pair2[1] } # => [:baz, 2] + # [].max {|a, b| a <=> b } # => nil + # + # With a block given and positive integer argument `n` given, returns an array + # containing the first `n` maximum elements that exist, as determined by the + # block. + # + # %w[xxx x xxxx xx].max(2) {|a, b| a.size <=> b.size } # => ["xxxx", "xxx"] + # h = {foo: 0, bar: 1, baz: 2} + # h.max(2) {|pair1, pair2| pair1[1] <=> pair2[1] } + # # => [[:baz, 2], [:bar, 1]] + # [].max(2) {|a, b| a <=> b } # => [] + # + # Related: #min, #minmax, #max_by. + # def max: () -> Elem? | () { (Elem arg0, Elem arg1) -> Integer } -> Elem? | (Integer arg0) -> ::Array[Elem] | (Integer arg0) { (Elem arg0, Elem arg1) -> Integer } -> ::Array[Elem] + # <!-- + # rdoc-file=enum.c + # - max_by {|element| ... } -> element + # - max_by(n) {|element| ... } -> array + # - max_by -> enumerator + # - max_by(n) -> enumerator + # --> + # Returns the elements for which the block returns the maximum values. + # + # With a block given and no argument, returns the element for which the block + # returns the maximum value: + # + # (1..4).max_by {|element| -element } # => 1 + # %w[a b c d].max_by {|element| -element.ord } # => "a" + # {foo: 0, bar: 1, baz: 2}.max_by {|key, value| -value } # => [:foo, 0] + # [].max_by {|element| -element } # => nil + # + # With a block given and positive integer argument `n` given, returns an array + # containing the `n` elements for which the block returns maximum values: + # + # (1..4).max_by(2) {|element| -element } + # # => [1, 2] + # %w[a b c d].max_by(2) {|element| -element.ord } + # # => ["a", "b"] + # {foo: 0, bar: 1, baz: 2}.max_by(2) {|key, value| -value } + # # => [[:foo, 0], [:bar, 1]] + # [].max_by(2) {|element| -element } + # # => [] + # + # Returns an Enumerator if no block is given. + # + # Related: #max, #minmax, #min_by. + # def max_by: () -> ::Enumerator[Elem, Elem?] | () { (Elem arg0) -> (Comparable | ::Array[untyped]) } -> Elem? | (Integer arg0) -> ::Enumerator[Elem, ::Array[Elem]] | (Integer arg0) { (Elem arg0) -> (Comparable | ::Array[untyped]) } -> ::Array[Elem] - # Returns the object in *enum* with the minimum value. The first form - # assumes all objects implement `Comparable` ; the second uses the block - # to return *a \<=\> b* . + # <!-- + # rdoc-file=enum.c + # - min -> element + # - min(n) -> array + # - min {|a, b| ... } -> element + # - min(n) {|a, b| ... } -> array + # --> + # Returns the element with the minimum element according to a given criterion. + # The ordering of equal elements is indeterminate and may be unstable. # - # ```ruby - # a = %w(albatross dog horse) - # a.min #=> "albatross" - # a.min { |a, b| a.length <=> b.length } #=> "dog" - # ``` + # With no argument and no block, returns the minimum element, using the + # elements' own method `<=>` for comparison: # - # If the `n` argument is given, minimum `n` elements are returned as a - # sorted array. + # (1..4).min # => 1 + # (-4..-1).min # => -4 + # %w[d c b a].min # => "a" + # {foo: 0, bar: 1, baz: 2}.min # => [:bar, 1] + # [].min # => nil # - # ```ruby - # a = %w[albatross dog horse] - # a.min(2) #=> ["albatross", "dog"] - # a.min(2) {|a, b| a.length <=> b.length } #=> ["dog", "horse"] - # [5, 1, 3, 4, 2].min(3) #=> [1, 2, 3] - # ``` + # With positive integer argument `n` given, and no block, returns an array + # containing the first `n` minimum elements that exist: + # + # (1..4).min(2) # => [1, 2] + # (-4..-1).min(2) # => [-4, -3] + # %w[d c b a].min(2) # => ["a", "b"] + # {foo: 0, bar: 1, baz: 2}.min(2) # => [[:bar, 1], [:baz, 2]] + # [].min(2) # => [] + # + # With a block given, the block determines the minimum elements. The block is + # called with two elements `a` and `b`, and must return: + # + # * A negative integer if `a < b`. + # * Zero if `a == b`. + # * A positive integer if `a > b`. + # + # + # With a block given and no argument, returns the minimum element as determined + # by the block: + # + # %w[xxx x xxxx xx].min {|a, b| a.size <=> b.size } # => "x" + # h = {foo: 0, bar: 1, baz: 2} + # h.min {|pair1, pair2| pair1[1] <=> pair2[1] } # => [:foo, 0] + # [].min {|a, b| a <=> b } # => nil + # + # With a block given and positive integer argument `n` given, returns an array + # containing the first `n` minimum elements that exist, as determined by the + # block. + # + # %w[xxx x xxxx xx].min(2) {|a, b| a.size <=> b.size } # => ["x", "xx"] + # h = {foo: 0, bar: 1, baz: 2} + # h.min(2) {|pair1, pair2| pair1[1] <=> pair2[1] } + # # => [[:foo, 0], [:bar, 1]] + # [].min(2) {|a, b| a <=> b } # => [] + # + # Related: #min_by, #minmax, #max. + # def min: () -> Elem? | () { (Elem arg0, Elem arg1) -> Integer } -> Elem? | (Integer arg0) -> ::Array[Elem] | (Integer arg0) { (Elem arg0, Elem arg1) -> Integer } -> ::Array[Elem] + # <!-- + # rdoc-file=enum.c + # - min_by {|element| ... } -> element + # - min_by(n) {|element| ... } -> array + # - min_by -> enumerator + # - min_by(n) -> enumerator + # --> + # Returns the elements for which the block returns the minimum values. + # + # With a block given and no argument, returns the element for which the block + # returns the minimum value: + # + # (1..4).min_by {|element| -element } # => 4 + # %w[a b c d].min_by {|element| -element.ord } # => "d" + # {foo: 0, bar: 1, baz: 2}.min_by {|key, value| -value } # => [:baz, 2] + # [].min_by {|element| -element } # => nil + # + # With a block given and positive integer argument `n` given, returns an array + # containing the `n` elements for which the block returns minimum values: + # + # (1..4).min_by(2) {|element| -element } + # # => [4, 3] + # %w[a b c d].min_by(2) {|element| -element.ord } + # # => ["d", "c"] + # {foo: 0, bar: 1, baz: 2}.min_by(2) {|key, value| -value } + # # => [[:baz, 2], [:bar, 1]] + # [].min_by(2) {|element| -element } + # # => [] + # + # Returns an Enumerator if no block is given. + # + # Related: #min, #minmax, #max_by. + # def min_by: () -> ::Enumerator[Elem, Elem?] | () { (Elem arg0) -> (Comparable | ::Array[untyped]) } -> Elem? | (Integer arg0) -> ::Enumerator[Elem, ::Array[Elem]] | (Integer arg0) { (Elem arg0) -> (Comparable | ::Array[untyped]) } -> ::Array[Elem] - # Returns a two element 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* . + # <!-- + # rdoc-file=enum.c + # - minmax -> [minimum, maximum] + # - minmax {|a, b| ... } -> [minimum, maximum] + # --> + # Returns a 2-element array containing the minimum and maximum elements + # according to a given criterion. The ordering of equal elements is + # indeterminate and may be unstable. # - # ```ruby - # a = %w(albatross dog horse) - # a.minmax #=> ["albatross", "horse"] - # a.minmax { |a, b| a.length <=> b.length } #=> ["dog", "albatross"] - # ``` + # With no argument and no block, returns the minimum and maximum elements, using + # the elements' own method `<=>` for comparison: + # + # (1..4).minmax # => [1, 4] + # (-4..-1).minmax # => [-4, -1] + # %w[d c b a].minmax # => ["a", "d"] + # {foo: 0, bar: 1, baz: 2}.minmax # => [[:bar, 1], [:foo, 0]] + # [].minmax # => [nil, nil] + # + # With a block given, returns the minimum and maximum elements as determined by + # the block: + # + # %w[xxx x xxxx xx].minmax {|a, b| a.size <=> b.size } # => ["x", "xxxx"] + # h = {foo: 0, bar: 1, baz: 2} + # h.minmax {|pair1, pair2| pair1[1] <=> pair2[1] } + # # => [[:foo, 0], [:baz, 2]] + # [].minmax {|a, b| a <=> b } # => [nil, nil] + # + # Related: #min, #max, #minmax_by. + # def minmax: () -> [ Elem?, Elem? ] | () { (Elem arg0, Elem arg1) -> Integer } -> [ Elem?, Elem? ] + # <!-- + # rdoc-file=enum.c + # - minmax_by {|element| ... } -> [minimum, maximum] + # - minmax_by -> enumerator + # --> + # Returns a 2-element array containing the elements for which the block returns + # minimum and maximum values: + # + # (1..4).minmax_by {|element| -element } + # # => [4, 1] + # %w[a b c d].minmax_by {|element| -element.ord } + # # => ["d", "a"] + # {foo: 0, bar: 1, baz: 2}.minmax_by {|key, value| -value } + # # => [[:baz, 2], [:foo, 0]] + # [].minmax_by {|element| -element } + # # => [nil, nil] + # + # Returns an Enumerator if no block is given. + # + # Related: #max_by, #minmax, #min_by. + # def minmax_by: () -> [ Elem?, Elem? ] | () { (Elem arg0) -> (Comparable | ::Array[untyped]) } -> [ Elem?, Elem? ] - # 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. + # <!-- + # rdoc-file=enum.c + # - none? -> true or false + # - none?(pattern) -> true or false + # - none? {|element| ... } -> true or false + # --> + # Returns whether no element meets a given criterion. # - # If instead a pattern is supplied, the method returns whether `pattern - # === element` for none of the collection members. + # With no argument and no block, returns whether no element is truthy: # - # ```ruby - # %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].none? #=> true - # [nil, false].none? #=> true - # [nil, false, true].none? #=> false - # ``` + # (1..4).none? # => false + # [nil, false].none? # => true + # {foo: 0}.none? # => false + # {foo: 0, bar: 1}.none? # => false + # [].none? # => true + # + # With argument `pattern` and no block, returns whether for no element + # `element`, `pattern === element`: + # + # [nil, false, 1.1].none?(Integer) # => true + # %w[bar baz bat bam].none?(/m/) # => false + # %w[bar baz bat bam].none?(/foo/) # => true + # %w[bar baz bat bam].none?('ba') # => true + # {foo: 0, bar: 1, baz: 2}.none?(Hash) # => true + # {foo: 0}.none?(Array) # => false + # [].none?(Integer) # => true + # + # With a block given, returns whether the block returns a truthy value for no + # element: + # + # (1..4).none? {|element| element < 1 } # => true + # (1..4).none? {|element| element < 2 } # => false + # {foo: 0, bar: 1, baz: 2}.none? {|key, value| value < 0 } # => true + # {foo: 0, bar: 1, baz: 2}.none? {|key, value| value < 1 } # => false + # + # Related: #one?, #all?, #any?. + # def none?: () -> bool | () { (Elem) -> boolish } -> bool - # 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. + # <!-- + # rdoc-file=enum.c + # - one? -> true or false + # - one?(pattern) -> true or false + # - one? {|element| ... } -> true or false + # --> + # Returns whether exactly one element meets a given criterion. # - # If instead a pattern is supplied, the method returns whether `pattern - # === element` for exactly one collection member. + # With no argument and no block, returns whether exactly one element is truthy: # - # ```ruby - # %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 - # ``` + # (1..1).one? # => true + # [1, nil, false].one? # => true + # (1..4).one? # => false + # {foo: 0}.one? # => true + # {foo: 0, bar: 1}.one? # => false + # [].one? # => false + # + # With argument `pattern` and no block, returns whether for exactly one element + # `element`, `pattern === element`: + # + # [nil, false, 0].one?(Integer) # => true + # [nil, false, 0].one?(Numeric) # => true + # [nil, false, 0].one?(Float) # => false + # %w[bar baz bat bam].one?(/m/) # => true + # %w[bar baz bat bam].one?(/foo/) # => false + # %w[bar baz bat bam].one?('ba') # => false + # {foo: 0, bar: 1, baz: 2}.one?(Array) # => false + # {foo: 0}.one?(Array) # => true + # [].one?(Integer) # => false + # + # With a block given, returns whether the block returns a truthy value for + # exactly one element: + # + # (1..4).one? {|element| element < 2 } # => true + # (1..4).one? {|element| element < 1 } # => false + # {foo: 0, bar: 1, baz: 2}.one? {|key, value| value < 1 } # => true + # {foo: 0, bar: 1, baz: 2}.one? {|key, value| value < 2 } # => false + # + # Related: #none?, #all?, #any?. + # def one?: () -> bool | () { (Elem) -> boolish } -> bool + # <!-- + # rdoc-file=enum.c + # - partition {|element| ... } -> [true_array, false_array] + # - partition -> enumerator + # --> + # With a block given, returns an array of two arrays: + # + # * The first having those elements for which the block returns a truthy + # value. + # * The other having all other elements. + # + # + # Examples: + # + # p = (1..4).partition {|i| i.even? } + # p # => [[2, 4], [1, 3]] + # p = ('a'..'d').partition {|c| c < 'c' } + # p # => [["a", "b"], ["c", "d"]] + # h = {foo: 0, bar: 1, baz: 2, bat: 3} + # p = h.partition {|key, value| key.start_with?('b') } + # p # => [[[:bar, 1], [:baz, 2], [:bat, 3]], [[:foo, 0]]] + # p = h.partition {|key, value| value < 2 } + # p # => [[[:foo, 0], [:bar, 1]], [[:baz, 2], [:bat, 3]]] + # + # With no block given, returns an Enumerator. + # + # Related: Enumerable#group_by. + # def partition: () { (Elem) -> boolish } -> [ ::Array[Elem], ::Array[Elem] ] | () -> ::Enumerator[Elem, [ ::Array[Elem], ::Array[Elem] ]] + # <!-- + # rdoc-file=enum.c + # - reject {|element| ... } -> array + # - reject -> enumerator + # --> + # Returns an array of objects rejected by the block. + # + # With a block given, calls the block with successive elements; returns an array + # of those elements for which the block returns `nil` or `false`: + # + # (0..9).reject {|i| i * 2 if i.even? } # => [1, 3, 5, 7, 9] + # {foo: 0, bar: 1, baz: 2}.reject {|key, value| key if value.odd? } # => {:foo=>0, :baz=>2} + # + # When no block given, returns an Enumerator. + # + # Related: #select. + # def reject: () { (Elem) -> boolish } -> ::Array[Elem] | () -> ::Enumerator[Elem, ::Array[Elem]] + # <!-- + # rdoc-file=enum.c + # - reverse_each(*args) {|element| ... } -> self + # - reverse_each(*args) -> enumerator + # --> + # With a block given, calls the block with each element, but in reverse order; + # returns `self`: + # + # a = [] + # (1..4).reverse_each {|element| a.push(-element) } # => 1..4 + # a # => [-4, -3, -2, -1] + # + # a = [] + # %w[a b c d].reverse_each {|element| a.push(element) } + # # => ["a", "b", "c", "d"] + # a # => ["d", "c", "b", "a"] + # + # a = [] + # h.reverse_each {|element| a.push(element) } + # # => {:foo=>0, :bar=>1, :baz=>2} + # a # => [[:baz, 2], [:bar, 1], [:foo, 0]] + # + # With no block given, returns an Enumerator. + # def reverse_each: () { (Elem arg0) -> untyped } -> void | () -> ::Enumerator[Elem, void] - # Returns an array containing the items in *enum* sorted. + # <!-- + # rdoc-file=enum.c + # - sort -> array + # - sort {|a, b| ... } -> array + # --> + # Returns an array containing the sorted elements of `self`. The ordering of + # equal elements is indeterminate and may be unstable. # - # Comparisons for the sort will be done using the items’ own `<=>` - # operator or using an optional code block. + # With no block given, the sort compares using the elements' own method `<=>`: # - # The block must implement a comparison between `a` and `b` and return an - # integer less than 0 when `b` follows `a`, `0` when `a` and `b` are - # equivalent, or an integer greater than 0 when `a` follows `b` . + # %w[b c a d].sort # => ["a", "b", "c", "d"] + # {foo: 0, bar: 1, baz: 2}.sort # => [[:bar, 1], [:baz, 2], [:foo, 0]] # - # The result is not guaranteed to be stable. When the comparison of two - # elements returns `0`, the order of the elements is unpredictable. + # With a block given, comparisons in the block determine the ordering. The block + # is called with two elements `a` and `b`, and must return: # - # ```ruby - # %w(rhea kea flea).sort #=> ["flea", "kea", "rhea"] - # (1..10).sort { |a, b| b <=> a } #=> [10, 9, 8, 7, 6, 5, 4, 3, 2, 1] - # ``` + # * A negative integer if `a < b`. + # * Zero if `a == b`. + # * A positive integer if `a > b`. # - # See also [\#sort\_by](Enumerable.downloaded.ruby_doc#method-i-sort_by). - # It implements a Schwartzian transform which is useful when key - # computation or comparison is expensive. + # + # Examples: + # + # a = %w[b c a d] + # a.sort {|a, b| b <=> a } # => ["d", "c", "b", "a"] + # h = {foo: 0, bar: 1, baz: 2} + # h.sort {|a, b| b <=> a } # => [[:foo, 0], [:baz, 2], [:bar, 1]] + # + # See also #sort_by. It implements a Schwartzian transform which is useful when + # key computation or comparison is expensive. + # def sort: () -> ::Array[Elem] | () { (Elem arg0, Elem arg1) -> Integer } -> ::Array[Elem] + # <!-- + # rdoc-file=enum.c + # - sort_by {|element| ... } -> array + # - sort_by -> enumerator + # --> + # With a block given, returns an array of elements of `self`, sorted according + # to the value returned by the block for each element. The ordering of equal + # elements is indeterminate and may be unstable. + # + # Examples: + # + # a = %w[xx xxx x xxxx] + # a.sort_by {|s| s.size } # => ["x", "xx", "xxx", "xxxx"] + # a.sort_by {|s| -s.size } # => ["xxxx", "xxx", "xx", "x"] + # h = {foo: 2, bar: 1, baz: 0} + # h.sort_by{|key, value| value } # => [[:baz, 0], [:bar, 1], [:foo, 2]] + # h.sort_by{|key, value| key } # => [[:bar, 1], [:baz, 0], [:foo, 2]] + # + # With no block given, returns an Enumerator. + # + # The current implementation of #sort_by generates an array of tuples containing + # the original collection element and the mapped value. This makes #sort_by + # fairly expensive when the keysets are simple. + # + # require 'benchmark' + # + # a = (1..100000).map { rand(100000) } + # + # Benchmark.bm(10) do |b| + # b.report("Sort") { a.sort } + # b.report("Sort by") { a.sort_by { |a| a } } + # end + # + # *produces:* + # + # user system total real + # Sort 0.180000 0.000000 0.180000 ( 0.175469) + # Sort by 1.980000 0.040000 2.020000 ( 2.013586) + # + # However, consider the case where comparing the keys is a non-trivial + # operation. The following code sorts some files on modification time using the + # basic #sort method. + # + # files = Dir["*"] + # sorted = files.sort { |a, b| File.new(a).mtime <=> File.new(b).mtime } + # sorted #=> ["mon", "tues", "wed", "thurs"] + # + # This sort is inefficient: it generates two new File objects during every + # comparison. A slightly better technique is to use the Kernel#test method to + # generate the modification times directly. + # + # files = Dir["*"] + # sorted = files.sort { |a, b| + # test(?M, a) <=> test(?M, b) + # } + # sorted #=> ["mon", "tues", "wed", "thurs"] + # + # This still generates many unnecessary Time objects. A more efficient technique + # is to cache the sort keys (modification times in this case) before the sort. + # Perl users often call this approach a Schwartzian transform, after Randal + # Schwartz. We construct a temporary array, where each element is an array + # containing our sort key along with the filename. We sort this array, and then + # extract the filename from the result. + # + # sorted = Dir["*"].collect { |f| + # [test(?M, f), f] + # }.sort.collect { |f| f[1] } + # sorted #=> ["mon", "tues", "wed", "thurs"] + # + # This is exactly what #sort_by does internally. + # + # sorted = Dir["*"].sort_by { |f| test(?M, f) } + # sorted #=> ["mon", "tues", "wed", "thurs"] + # + # To produce the reverse of a specific order, the following can be used: + # + # ary.sort_by { ... }.reverse! + # def sort_by: () { (Elem arg0) -> (Comparable | ::Array[untyped]) } -> ::Array[Elem] | () -> ::Enumerator[Elem, ::Array[Elem]] - # Returns first n elements from *enum*. + # <!-- + # rdoc-file=enum.c + # - take(n) -> array + # --> + # For non-negative integer `n`, returns the first `n` elements: # - # a = [1, 2, 3, 4, 5, 0] - # a.take(3) #=> [1, 2, 3] - # a.take(30) #=> [1, 2, 3, 4, 5, 0] + # r = (1..4) + # r.take(2) # => [1, 2] + # r.take(0) # => [] # + # h = {foo: 0, bar: 1, baz: 2, bat: 3} + # h.take(2) # => [[:foo, 0], [:bar, 1]] + # def take: (Integer n) -> ::Array[Elem] - # Passes elements to the block until the block returns `nil` or `false`, then - # stops iterating and returns an array of all prior elements. + # <!-- + # rdoc-file=enum.c + # - take_while {|element| ... } -> array + # - take_while -> enumerator + # --> + # Calls the block with successive elements as long as the block returns a truthy + # value; returns an array of all elements up to that point: # - # If no block is given, an enumerator is returned instead. + # (1..4).take_while{|i| i < 3 } # => [1, 2] + # h = {foo: 0, bar: 1, baz: 2} + # h.take_while{|element| key, value = *element; value < 2 } + # # => [[:foo, 0], [:bar, 1]] # - # a = [1, 2, 3, 4, 5, 0] - # a.take_while { |i| i < 3 } #=> [1, 2] + # With no block given, returns an Enumerator. # def take_while: () { (Elem) -> boolish } -> ::Array[Elem] | () -> ::Enumerator[Elem, ::Array[Elem]] - # Implemented in C++ - # Returns the result of interpreting *enum* as a list of `[key, value]` - # pairs. + # <!-- + # rdoc-file=enum.c + # - to_h -> hash + # - to_h {|element| ... } -> hash + # --> + # When `self` consists of 2-element arrays, returns a hash each of whose entries + # is the key-value pair formed from one of those arrays: # - # %i[hello world].each_with_index.to_h - # # => {:hello => 0, :world => 1} + # [[:foo, 0], [:bar, 1], [:baz, 2]].to_h # => {:foo=>0, :bar=>1, :baz=>2} # - # If a block is given, the results of the block on each element of the - # enum will be used as pairs. + # When a block is given, the block is called with each element of `self`; the + # block should return a 2-element array which becomes a key-value pair in the + # returned hash: # - # ```ruby - # (1..5).to_h {|x| [x, x ** 2]} - # #=> {1=>1, 2=>4, 3=>9, 4=>16, 5=>25} - # ``` + # (0..3).to_h {|i| [i, i ** 2]} # => {0=>0, 1=>1, 2=>4, 3=>9} + # + # Raises an exception if an element of `self` is not a 2-element array, and a + # block is not passed. + # def to_h: () -> ::Hash[untyped, untyped] - | [T, U] () { (Elem) -> [T, U] } -> ::Hash[T, U] + | [T, U] () { (Elem) -> [ T, U ] } -> ::Hash[T, U] - def each_slice: (Integer n) { (::Array[Elem]) -> untyped } -> NilClass - | (Integer n) -> ::Enumerator[::Array[Elem], NilClass] + # <!-- + # rdoc-file=enum.c + # - each_slice(n) { ... } -> self + # - each_slice(n) -> enumerator + # --> + # Calls the block with each successive disjoint `n`-tuple of elements; returns + # `self`: + # + # a = [] + # (1..10).each_slice(3) {|tuple| a.push(tuple) } + # a # => [[1, 2, 3], [4, 5, 6], [7, 8, 9], [10]] + # + # a = [] + # h = {foo: 0, bar: 1, baz: 2, bat: 3, bam: 4} + # h.each_slice(2) {|tuple| a.push(tuple) } + # a # => [[[:foo, 0], [:bar, 1]], [[:baz, 2], [:bat, 3]], [[:bam, 4]]] + # + # With no block given, returns an Enumerator. + # + def each_slice: (Integer n) { (::Array[Elem]) -> void } -> self + | (Integer n) -> ::Enumerator[::Array[Elem], self] interface _NotFound[T] def call: () -> T end + # <!-- + # rdoc-file=enum.c + # - find(if_none_proc = nil) {|element| ... } -> object or nil + # - find(if_none_proc = nil) -> enumerator + # --> + # Returns the first element for which the block returns a truthy value. + # + # With a block given, calls the block with successive elements of the + # collection; returns the first element for which the block returns a truthy + # value: + # + # (0..9).find {|element| element > 2} # => 3 + # + # If no such element is found, calls `if_none_proc` and returns its return + # value. + # + # (0..9).find(proc {false}) {|element| element > 12} # => false + # {foo: 0, bar: 1, baz: 2}.find {|key, value| key.start_with?('b') } # => [:bar, 1] + # {foo: 0, bar: 1, baz: 2}.find(proc {[]}) {|key, value| key.start_with?('c') } # => [] + # + # With no block given, returns an Enumerator. + # def find: () { (Elem) -> boolish } -> Elem? | () -> ::Enumerator[Elem, Elem?] | [T] (_NotFound[T] ifnone) { (Elem) -> boolish } -> (Elem | T) | [T] (_NotFound[T] ifnone) -> ::Enumerator[Elem, Elem | T] + # <!-- + # rdoc-file=enum.c + # - flat_map {|element| ... } -> array + # - flat_map -> enumerator + # --> + # Returns an array of flattened objects returned by the block. + # + # With a block given, calls the block with successive elements; returns a + # flattened array of objects returned by the block: + # + # [0, 1, 2, 3].flat_map {|element| -element } # => [0, -1, -2, -3] + # [0, 1, 2, 3].flat_map {|element| [element, -element] } # => [0, 0, 1, -1, 2, -2, 3, -3] + # [[0, 1], [2, 3]].flat_map {|e| e + [100] } # => [0, 1, 100, 2, 3, 100] + # {foo: 0, bar: 1, baz: 2}.flat_map {|key, value| [key, value] } # => [:foo, 0, :bar, 1, :baz, 2] + # + # With no block given, returns an Enumerator. + # + # Alias: #collect_concat. + # def flat_map: [U] () { (Elem) -> (Array[U] | U) } -> Array[U] | () -> ::Enumerator[Elem, Array[untyped]] + # <!-- rdoc-file=enum.c --> + # Returns an array of objects returned by the block. + # + # With a block given, calls the block with successive elements; returns an array + # of the objects returned by the block: + # + # (0..4).map {|i| i*i } # => [0, 1, 4, 9, 16] + # {foo: 0, bar: 1, baz: 2}.map {|key, value| value*2} # => [0, 2, 4] + # + # With no block given, returns an Enumerator. + # def map: [U] () { (Elem arg0) -> U } -> ::Array[U] | () -> ::Enumerator[Elem, ::Array[untyped]] + # <!-- + # rdoc-file=enum.c + # - include?(object) -> true or false + # --> + # Returns whether for any element `object == element`: + # + # (1..4).include?(2) # => true + # (1..4).include?(5) # => false + # (1..4).include?('2') # => false + # %w[a b c d].include?('b') # => true + # %w[a b c d].include?('2') # => false + # {foo: 0, bar: 1, baz: 2}.include?(:foo) # => true + # {foo: 0, bar: 1, baz: 2}.include?('foo') # => false + # {foo: 0, bar: 1, baz: 2}.include?(0) # => false + # + # Enumerable#member? is an alias for Enumerable#include?. + # def member?: (Elem arg0) -> bool + # <!-- rdoc-file=enum.c --> + # Returns an object formed from operands via either: + # + # * A method named by `symbol`. + # * A block to which each operand is passed. + # + # + # With method-name argument `symbol`, combines operands using the method: + # + # # Sum, without initial_operand. + # (1..4).inject(:+) # => 10 + # # Sum, with initial_operand. + # (1..4).inject(10, :+) # => 20 + # + # With a block, passes each operand to the block: + # + # # Sum of squares, without initial_operand. + # (1..4).inject {|sum, n| sum + n*n } # => 30 + # # Sum of squares, with initial_operand. + # (1..4).inject(2) {|sum, n| sum + n*n } # => 32 + # + # **Operands** + # + # If argument `initial_operand` is not given, the operands for `inject` are + # simply the elements of `self`. Example calls and their operands: + # + # `(1..4).inject(:+)` + # : `[1, 2, 3, 4]`. + # + # `(1...4).inject(:+)` + # : `[1, 2, 3]`. + # + # `('a'..'d').inject(:+)` + # : `['a', 'b', 'c', 'd']`. + # + # `('a'...'d').inject(:+)` + # : `['a', 'b', 'c']`. + # + # + # + # Examples with first operand (which is `self.first`) of various types: + # + # # Integer. + # (1..4).inject(:+) # => 10 + # # Float. + # [1.0, 2, 3, 4].inject(:+) # => 10.0 + # # Character. + # ('a'..'d').inject(:+) # => "abcd" + # # Complex. + # [Complex(1, 2), 3, 4].inject(:+) # => (8+2i) + # + # If argument `initial_operand` is given, the operands for `inject` are that + # value plus the elements of `self`. Example calls their operands: + # + # `(1..4).inject(10, :+)` + # : `[10, 1, 2, 3, 4]`. + # + # `(1...4).inject(10, :+)` + # : `[10, 1, 2, 3]`. + # + # `('a'..'d').inject('e', :+)` + # : `['e', 'a', 'b', 'c', 'd']`. + # + # `('a'...'d').inject('e', :+)` + # : `['e', 'a', 'b', 'c']`. + # + # + # + # Examples with `initial_operand` of various types: + # + # # Integer. + # (1..4).inject(2, :+) # => 12 + # # Float. + # (1..4).inject(2.0, :+) # => 12.0 + # # String. + # ('a'..'d').inject('foo', :+) # => "fooabcd" + # # Array. + # %w[a b c].inject(['x'], :push) # => ["x", "a", "b", "c"] + # # Complex. + # (1..4).inject(Complex(2, 2), :+) # => (12+2i) + # + # **Combination by Given \Method** + # + # If the method-name argument `symbol` is given, the operands are combined by + # that method: + # + # * The first and second operands are combined. + # * That result is combined with the third operand. + # * That result is combined with the fourth operand. + # * And so on. + # + # + # The return value from `inject` is the result of the last combination. + # + # This call to `inject` computes the sum of the operands: + # + # (1..4).inject(:+) # => 10 + # + # Examples with various methods: + # + # # Integer addition. + # (1..4).inject(:+) # => 10 + # # Integer multiplication. + # (1..4).inject(:*) # => 24 + # # Character range concatenation. + # ('a'..'d').inject('', :+) # => "abcd" + # # String array concatenation. + # %w[foo bar baz].inject('', :+) # => "foobarbaz" + # # Hash update. + # h = [{foo: 0, bar: 1}, {baz: 2}, {bat: 3}].inject(:update) + # h # => {:foo=>0, :bar=>1, :baz=>2, :bat=>3} + # # Hash conversion to nested arrays. + # h = {foo: 0, bar: 1}.inject([], :push) + # h # => [[:foo, 0], [:bar, 1]] + # + # **Combination by Given Block** + # + # If a block is given, the operands are passed to the block: + # + # * The first call passes the first and second operands. + # * The second call passes the result of the first call, along with the third + # operand. + # * The third call passes the result of the second call, along with the fourth + # operand. + # * And so on. + # + # + # The return value from `inject` is the return value from the last block call. + # + # This call to `inject` gives a block that writes the memo and element, and also + # sums the elements: + # + # (1..4).inject do |memo, element| + # p "Memo: #{memo}; element: #{element}" + # memo + element + # end # => 10 + # + # Output: + # + # "Memo: 1; element: 2" + # "Memo: 3; element: 3" + # "Memo: 6; element: 4" + # + # Enumerable#reduce is an alias for Enumerable#inject. + # alias reduce inject - # Returns an array containing the items in *enum* . + # <!-- + # rdoc-file=enum.c + # - to_a -> array + # --> + # Returns an array containing the items in `self`: # - # ```ruby - # (1..7).to_a #=> [1, 2, 3, 4, 5, 6, 7] - # { 'a'=>1, 'b'=>2, 'c'=>3 }.to_a #=> [["a", 1], ["b", 2], ["c", 3]] + # (0..4).to_a # => [0, 1, 2, 3, 4] # - # require 'prime' - # Prime.entries 10 #=> [2, 3, 5, 7] - # ``` + # Enumerable#entries is an alias for Enumerable#to_a. + # def to_a: () -> ::Array[Elem] - # Returns a lazy enumerator, whose methods map/collect, - # flat\_map/collect\_concat, select/find\_all, reject, grep, - # [\#grep\_v](Enumerable.downloaded.ruby_doc#method-i-grep_v), zip, take, - # [\#take\_while](Enumerable.downloaded.ruby_doc#method-i-take_while), - # drop, and - # [\#drop\_while](Enumerable.downloaded.ruby_doc#method-i-drop_while) - # enumerate values only on an as-needed basis. However, if a block is - # given to zip, values are enumerated immediately. + # <!-- + # rdoc-file=enumerator.c + # - e.lazy -> lazy_enumerator + # --> + # Returns an Enumerator::Lazy, which redefines most Enumerable methods to + # postpone enumeration and enumerate values only on an as-needed basis. # + # ### Example # # The following program finds pythagorean triples: # - # ```ruby - # def pythagorean_triples - # (1..Float::INFINITY).lazy.flat_map {|z| - # (1..z).flat_map {|x| - # (x..z).select {|y| - # x**2 + y**2 == z**2 - # }.map {|y| - # [x, y, z] + # def pythagorean_triples + # (1..Float::INFINITY).lazy.flat_map {|z| + # (1..z).flat_map {|x| + # (x..z).select {|y| + # x**2 + y**2 == z**2 + # }.map {|y| + # [x, y, z] + # } + # } # } - # } - # } - # end - # # show first ten pythagorean triples - # p pythagorean_triples.take(10).force # take is lazy, so force is needed - # p pythagorean_triples.first(10) # first is eager - # # show pythagorean triples less than 100 - # p pythagorean_triples.take_while { |*, z| z < 100 }.force - # ``` + # end + # # show first ten pythagorean triples + # p pythagorean_triples.take(10).force # take is lazy, so force is needed + # p pythagorean_triples.first(10) # first is eager + # # show pythagorean triples less than 100 + # p pythagorean_triples.take_while { |*, z| z < 100 }.force + # def lazy: () -> Enumerator::Lazy[Elem, void] + # <!-- + # rdoc-file=enum.c + # - uniq -> array + # - uniq {|element| ... } -> array + # --> + # With no block, returns a new array containing only unique elements; the array + # has no two elements `e0` and `e1` such that `e0.eql?(e1)`: + # + # %w[a b c c b a a b c].uniq # => ["a", "b", "c"] + # [0, 1, 2, 2, 1, 0, 0, 1, 2].uniq # => [0, 1, 2] + # + # With a block, returns a new array containing only for which the block returns + # a unique value: + # + # a = [0, 1, 2, 3, 4, 5, 5, 4, 3, 2, 1] + # a.uniq {|i| i.even? ? i : 0 } # => [0, 2, 4] + # a = %w[a b c d e e d c b a a b c d e] + # a.uniq {|c| c < 'c' } # => ["a", "c"] + # def uniq: () -> ::Array[Elem] | () { (Elem item) -> untyped } -> ::Array[Elem] + # <!-- + # rdoc-file=enum.c + # - sum(initial_value = 0) -> number + # - sum(initial_value = 0) {|element| ... } -> object + # --> + # With no block given, returns the sum of `initial_value` and the elements: + # + # (1..100).sum # => 5050 + # (1..100).sum(1) # => 5051 + # ('a'..'d').sum('foo') # => "fooabcd" + # + # Generally, the sum is computed using methods `+` and `each`; for performance + # optimizations, those methods may not be used, and so any redefinition of those + # methods may not have effect here. + # + # One such optimization: When possible, computes using Gauss's summation formula + # *n(n+1)/2*: + # + # 100 * (100 + 1) / 2 # => 5050 + # + # With a block given, calls the block with each element; returns the sum of + # `initial_value` and the block return values: + # + # (1..4).sum {|i| i*i } # => 30 + # (1..4).sum(100) {|i| i*i } # => 130 + # h = {a: 0, b: 1, c: 2, d: 3, e: 4, f: 5} + # h.sum {|key, value| value.odd? ? value : 0 } # => 9 + # ('a'..'f').sum('x') {|c| c < 'd' ? c : '' } # => "xabc" + # def sum: () -> (Elem | Integer) | [T] () { (Elem arg0) -> T } -> (Integer | T) | [T] (?T arg0) -> (Elem | T) | [U] (?U arg0) { (Elem arg0) -> U } -> U + # <!-- + # rdoc-file=enum.c + # - filter_map {|element| ... } -> array + # - filter_map -> enumerator + # --> + # Returns an array containing truthy elements returned by the block. + # + # With a block given, calls the block with successive elements; returns an array + # containing each truthy value returned by the block: + # + # (0..9).filter_map {|i| i * 2 if i.even? } # => [0, 4, 8, 12, 16] + # {foo: 0, bar: 1, baz: 2}.filter_map {|key, value| key if value.even? } # => [:foo, :baz] + # + # When no block given, returns an Enumerator. + # def filter_map: [U] () { (Elem elem) -> (nil | false | U) } -> ::Array[U] | () -> ::Enumerator[Elem, ::Array[untyped]] + # <!-- + # rdoc-file=enumerator.c + # - e.chain(*enums) -> enumerator + # --> + # Returns an enumerator object generated from this enumerator and given + # enumerables. + # + # e = (1..3).chain([4, 5]) + # e.to_a #=> [1, 2, 3, 4, 5] + # def chain: (*self enumerables) -> ::Enumerator::Chain[Elem] - def tally: () -> ::Hash[Elem, Integer] + # <!-- + # rdoc-file=enum.c + # - tally -> new_hash + # - tally(hash) -> hash + # --> + # Returns a hash containing the counts of equal elements: + # + # * Each key is an element of `self`. + # * Each value is the number elements equal to that key. + # + # + # With no argument: + # + # %w[a b c b c a c b].tally # => {"a"=>2, "b"=>3, "c"=>3} + # + # With a hash argument, that hash is used for the tally (instead of a new hash), + # and is returned; this may be useful for accumulating tallies across multiple + # enumerables: + # + # hash = {} + # hash = %w[a c d b c a].tally(hash) + # hash # => {"a"=>2, "c"=>2, "d"=>1, "b"=>1} + # hash = %w[b a z].tally(hash) + # hash # => {"a"=>3, "c"=>2, "d"=>1, "b"=>2, "z"=>1} + # hash = %w[b a m].tally(hash) + # hash # => {"a"=>4, "c"=>2, "d"=>1, "b"=>3, "z"=>1, "m"=> 1} + # + def tally: (?Hash[Elem, Integer] hash) -> ::Hash[Elem, Integer] + # <!-- + # rdoc-file=enum.c + # - each_entry(*args) {|element| ... } -> self + # - each_entry(*args) -> enumerator + # --> + # Calls the given block with each element, converting multiple values from yield + # to an array; returns `self`: + # + # a = [] + # (1..4).each_entry {|element| a.push(element) } # => 1..4 + # a # => [1, 2, 3, 4] + # + # a = [] + # h = {foo: 0, bar: 1, baz:2} + # h.each_entry {|element| a.push(element) } + # # => {:foo=>0, :bar=>1, :baz=>2} + # a # => [[:foo, 0], [:bar, 1], [:baz, 2]] + # + # class Foo + # include Enumerable + # def each + # yield 1 + # yield 1, 2 + # yield + # end + # end + # Foo.new.each_entry {|yielded| p yielded } + # + # Output: + # + # 1 + # [1, 2] + # nil + # + # With no block given, returns an Enumerator. + # def each_entry: () -> ::Enumerator[Elem, self] | () { (Elem arg0) -> untyped } -> self - # variadic type parameter is not supported yet - # https://github.com/ruby/rbs/issues/21 - def zip: [Elem2] (::Enumerable[Elem2] enum) -> ::Array[[Elem, Elem2 | nil]] - | [U, Elem2] (::Enumerable[Elem2]) { ([Elem, Elem2 | nil]) -> U } -> nil + # <!-- + # rdoc-file=enum.c + # - zip(*other_enums) -> array + # - zip(*other_enums) {|array| ... } -> nil + # --> + # With no block given, returns a new array `new_array` of size self.size whose + # elements are arrays. Each nested array `new_array[n]` is of size + # `other_enums.size+1`, and contains: + # + # * The `n`-th element of self. + # * The `n`-th element of each of the `other_enums`. + # + # + # If all `other_enums` and self are the same size, all elements are included in + # the result, and there is no `nil`-filling: + # + # a = [:a0, :a1, :a2, :a3] + # b = [:b0, :b1, :b2, :b3] + # c = [:c0, :c1, :c2, :c3] + # d = a.zip(b, c) + # d # => [[:a0, :b0, :c0], [:a1, :b1, :c1], [:a2, :b2, :c2], [:a3, :b3, :c3]] + # + # f = {foo: 0, bar: 1, baz: 2} + # g = {goo: 3, gar: 4, gaz: 5} + # h = {hoo: 6, har: 7, haz: 8} + # d = f.zip(g, h) + # d # => [ + # # [[:foo, 0], [:goo, 3], [:hoo, 6]], + # # [[:bar, 1], [:gar, 4], [:har, 7]], + # # [[:baz, 2], [:gaz, 5], [:haz, 8]] + # # ] + # + # If any enumerable in other_enums is smaller than self, fills to `self.size` + # with `nil`: + # + # a = [:a0, :a1, :a2, :a3] + # b = [:b0, :b1, :b2] + # c = [:c0, :c1] + # d = a.zip(b, c) + # d # => [[:a0, :b0, :c0], [:a1, :b1, :c1], [:a2, :b2, nil], [:a3, nil, nil]] + # + # If any enumerable in other_enums is larger than self, its trailing elements + # are ignored: + # + # a = [:a0, :a1, :a2, :a3] + # b = [:b0, :b1, :b2, :b3, :b4] + # c = [:c0, :c1, :c2, :c3, :c4, :c5] + # d = a.zip(b, c) + # d # => [[:a0, :b0, :c0], [:a1, :b1, :c1], [:a2, :b2, :c2], [:a3, :b3, :c3]] + # + # When a block is given, calls the block with each of the sub-arrays (formed as + # above); returns nil: + # + # a = [:a0, :a1, :a2, :a3] + # b = [:b0, :b1, :b2, :b3] + # c = [:c0, :c1, :c2, :c3] + # a.zip(b, c) {|sub_array| p sub_array} # => nil + # + # Output: + # + # [:a0, :b0, :c0] + # [:a1, :b1, :c1] + # [:a2, :b2, :c2] + # [:a3, :b3, :c3] + # + def zip: [Elem2] (::Enumerable[Elem2] enum) -> ::Array[[ Elem, Elem2 | nil ]] + | [U, Elem2] (::Enumerable[Elem2]) { ([ Elem, Elem2 | nil ]) -> U } -> nil - def chunk: [U] () { (Elem elt) -> U } -> ::Enumerator[[U, ::Array[Elem]], void] - | () -> ::Enumerator[Elem, ::Enumerator[[untyped, ::Array[Elem]], void]] + # <!-- + # rdoc-file=enum.c + # - chunk {|array| ... } -> enumerator + # --> + # Each element in the returned enumerator is a 2-element array consisting of: + # + # * A value returned by the block. + # * An array ("chunk") containing the element for which that value was + # returned, and all following elements for which the block returned the same + # value: + # + # + # So that: + # + # * Each block return value that is different from its predecessor begins a + # new chunk. + # * Each block return value that is the same as its predecessor continues the + # same chunk. + # + # + # Example: + # + # e = (0..10).chunk {|i| (i / 3).floor } # => #<Enumerator: ...> + # # The enumerator elements. + # e.next # => [0, [0, 1, 2]] + # e.next # => [1, [3, 4, 5]] + # e.next # => [2, [6, 7, 8]] + # e.next # => [3, [9, 10]] + # + # Method `chunk` is especially useful for an enumerable that is already sorted. + # This example counts words for each initial letter in a large array of words: + # + # # Get sorted words from a web page. + # url = 'https://raw.githubusercontent.com/eneko/data-repository/master/data/words.txt' + # words = URI::open(url).readlines + # # Make chunks, one for each letter. + # e = words.chunk {|word| word.upcase[0] } # => #<Enumerator: ...> + # # Display 'A' through 'F'. + # e.each {|c, words| p [c, words.length]; break if c == 'F' } + # + # Output: + # + # ["A", 17096] + # ["B", 11070] + # ["C", 19901] + # ["D", 10896] + # ["E", 8736] + # ["F", 6860] + # + # You can use the special symbol `:_alone` to force an element into its own + # separate chuck: + # + # a = [0, 0, 1, 1] + # e = a.chunk{|i| i.even? ? :_alone : true } + # e.to_a # => [[:_alone, [0]], [:_alone, [0]], [true, [1, 1]]] + # + # For example, you can put each line that contains a URL into its own chunk: + # + # pattern = /http/ + # open(filename) { |f| + # f.chunk { |line| line =~ pattern ? :_alone : true }.each { |key, lines| + # pp lines + # } + # } + # + # You can use the special symbol `:_separator` or `nil` to force an element to + # be ignored (not included in any chunk): + # + # a = [0, 0, -1, 1, 1] + # e = a.chunk{|i| i < 0 ? :_separator : true } + # e.to_a # => [[true, [0, 0]], [true, [1, 1]]] + # + # Note that the separator does end the chunk: + # + # a = [0, 0, -1, 1, -1, 1] + # e = a.chunk{|i| i < 0 ? :_separator : true } + # e.to_a # => [[true, [0, 0]], [true, [1]], [true, [1]]] + # + # For example, the sequence of hyphens in svn log can be eliminated as follows: + # + # sep = "-"*72 + "\n" + # IO.popen("svn log README") { |f| + # f.chunk { |line| + # line != sep || nil + # }.each { |_, lines| + # pp lines + # } + # } + # #=> ["r20018 | knu | 2008-10-29 13:20:42 +0900 (Wed, 29 Oct 2008) | 2 lines\n", + # # "\n", + # # "* README, README.ja: Update the portability section.\n", + # # "\n"] + # # ["r16725 | knu | 2008-05-31 23:34:23 +0900 (Sat, 31 May 2008) | 2 lines\n", + # # "\n", + # # "* README, README.ja: Add a note about default C flags.\n", + # # "\n"] + # # ... + # + # Paragraphs separated by empty lines can be parsed as follows: + # + # File.foreach("README").chunk { |line| + # /\A\s*\z/ !~ line || nil + # }.each { |_, lines| + # pp lines + # } + # + def chunk: [U] () { (Elem elt) -> U } -> ::Enumerator[[ U, ::Array[Elem] ], void] + | () -> ::Enumerator[Elem, ::Enumerator[[ untyped, ::Array[Elem] ], void]] + # <!-- + # rdoc-file=enum.c + # - chunk_while {|element, next_element| ... } -> enumerator + # --> + # The returned Enumerator uses the block to partition elements into arrays + # ("chunks"); it calls the block with each element and its successor; begins a + # new chunk if and only if the block returns a truthy value: + # + # Example: + # + # a = [1, 2, 4, 9, 10, 11, 12, 15, 16, 19, 20, 21] + # e = a.chunk_while {|i, j| j == i + 1 } + # e.each {|array| p array } + # + # Output: + # + # [1, 2] + # [4] + # [9, 10, 11, 12] + # [15, 16] + # [19, 20, 21] + # def chunk_while: () { (Elem elt_before, Elem elt_after) -> boolish } -> ::Enumerator[::Array[Elem], void] + # <!-- + # rdoc-file=enum.c + # - slice_when {|element, next_element| ... } -> enumerator + # --> + # The returned enumerator uses the block to partition elements into arrays + # ("slices"); it calls the block with each element and its successor; begins a + # new slice if and only if the block returns a truthy value: + # + # a = [0, 1, 2, 4, 5, 6, 8, 9] + # e = a.slice_when {|i, j| j != i + 1 } + # e.each {|array| p array } + # + # Output: + # + # [0, 1, 2] + # [4, 5, 6] + # [8, 9] + # def slice_when: () { (Elem elt_before, Elem elt_after) -> boolish } -> ::Enumerator[::Array[Elem], void] + # <!-- + # rdoc-file=enum.c + # - slice_after(pattern) -> enumerator + # - slice_after {|array| ... } -> enumerator + # --> + # With argument `pattern`, returns an enumerator that uses the pattern to + # partition elements into arrays ("slices"). An element ends the current slice + # if `element === pattern`: + # + # a = %w[foo bar fop for baz fob fog bam foy] + # e = a.slice_after(/ba/) # => #<Enumerator: ...> + # e.each {|array| p array } + # + # Output: + # + # ["foo", "bar"] + # ["fop", "for", "baz"] + # ["fob", "fog", "bam"] + # ["foy"] + # + # With a block, returns an enumerator that uses the block to partition elements + # into arrays. An element ends the current slice if its block return is a truthy + # value: + # + # e = (1..20).slice_after {|i| i % 4 == 2 } # => #<Enumerator: ...> + # e.each {|array| p array } + # + # Output: + # + # [1, 2] + # [3, 4, 5, 6] + # [7, 8, 9, 10] + # [11, 12, 13, 14] + # [15, 16, 17, 18] + # [19, 20] + # + # Other methods of the Enumerator class and Enumerable module, such as `map`, + # etc., are also usable. + # + # For example, continuation lines (lines end with backslash) can be concatenated + # as follows: + # + # lines = ["foo\n", "bar\\\n", "baz\n", "\n", "qux\n"] + # e = lines.slice_after(/(?<!\\)\n\z/) + # p e.to_a + # #=> [["foo\n"], ["bar\\\n", "baz\n"], ["\n"], ["qux\n"]] + # p e.map {|ll| ll[0...-1].map {|l| l.sub(/\\\n\z/, "") }.join + ll.last } + # #=>["foo\n", "barbaz\n", "\n", "qux\n"] + # def slice_after: (untyped pattern) -> ::Enumerator[::Array[Elem], void] | () { (Elem elt) -> boolish } -> ::Enumerator[::Array[Elem], void] + # <!-- + # rdoc-file=enum.c + # - slice_before(pattern) -> enumerator + # - slice_before {|array| ... } -> enumerator + # --> + # With argument `pattern`, returns an enumerator that uses the pattern to + # partition elements into arrays ("slices"). An element begins a new slice if + # `element === pattern` (or if it is the first element). + # + # a = %w[foo bar fop for baz fob fog bam foy] + # e = a.slice_before(/ba/) # => #<Enumerator: ...> + # e.each {|array| p array } + # + # Output: + # + # ["foo"] + # ["bar", "fop", "for"] + # ["baz", "fob", "fog"] + # ["bam", "foy"] + # + # With a block, returns an enumerator that uses the block to partition elements + # into arrays. An element begins a new slice if its block return is a truthy + # value (or if it is the first element): + # + # e = (1..20).slice_before {|i| i % 4 == 2 } # => #<Enumerator: ...> + # e.each {|array| p array } + # + # Output: + # + # [1] + # [2, 3, 4, 5] + # [6, 7, 8, 9] + # [10, 11, 12, 13] + # [14, 15, 16, 17] + # [18, 19, 20] + # + # Other methods of the Enumerator class and Enumerable module, such as `to_a`, + # `map`, etc., are also usable. + # + # For example, iteration over ChangeLog entries can be implemented as follows: + # + # # iterate over ChangeLog entries. + # open("ChangeLog") { |f| + # f.slice_before(/\A\S/).each { |e| pp e } + # } + # + # # same as above. block is used instead of pattern argument. + # open("ChangeLog") { |f| + # f.slice_before { |line| /\A\S/ === line }.each { |e| pp e } + # } + # + # "svn proplist -R" produces multiline output for each file. They can be chunked + # as follows: + # + # IO.popen([{"LC_ALL"=>"C"}, "svn", "proplist", "-R"]) { |f| + # f.lines.slice_before(/\AProp/).each { |lines| p lines } + # } + # #=> ["Properties on '.':\n", " svn:ignore\n", " svk:merge\n"] + # # ["Properties on 'goruby.c':\n", " svn:eol-style\n"] + # # ["Properties on 'complex.c':\n", " svn:mime-type\n", " svn:eol-style\n"] + # # ["Properties on 'regparse.c':\n", " svn:eol-style\n"] + # # ... + # + # If the block needs to maintain state over multiple elements, local variables + # can be used. For example, three or more consecutive increasing numbers can be + # squashed as follows (see `chunk_while` for a better way): + # + # a = [0, 2, 3, 4, 6, 7, 9] + # prev = a[0] + # p a.slice_before { |e| + # prev, prev2 = e, prev + # prev2 + 1 != e + # }.map { |es| + # es.length <= 2 ? es.join(",") : "#{es.first}-#{es.last}" + # }.join(",") + # #=> "0,2-4,6,7,9" + # + # However local variables should be used carefully if the result enumerator is + # enumerated twice or more. The local variables should be initialized for each + # enumeration. Enumerator.new can be used to do it. + # + # # Word wrapping. This assumes all characters have same width. + # def wordwrap(words, maxwidth) + # Enumerator.new {|y| + # # cols is initialized in Enumerator.new. + # cols = 0 + # words.slice_before { |w| + # cols += 1 if cols != 0 + # cols += w.length + # if maxwidth < cols + # cols = w.length + # true + # else + # false + # end + # }.each {|ws| y.yield ws } + # } + # end + # text = (1..20).to_a.join(" ") + # enum = wordwrap(text.split(/\s+/), 10) + # puts "-"*10 + # enum.each { |ws| puts ws.join(" ") } # first enumeration. + # puts "-"*10 + # enum.each { |ws| puts ws.join(" ") } # second enumeration generates same result as the first. + # puts "-"*10 + # #=> ---------- + # # 1 2 3 4 5 + # # 6 7 8 9 10 + # # 11 12 13 + # # 14 15 16 + # # 17 18 19 + # # 20 + # # ---------- + # # 1 2 3 4 5 + # # 6 7 8 9 10 + # # 11 12 13 + # # 14 15 16 + # # 17 18 19 + # # 20 + # # ---------- + # + # mbox contains series of mails which start with Unix From line. So each mail + # can be extracted by slice before Unix From line. + # + # # parse mbox + # open("mbox") { |f| + # f.slice_before { |line| + # line.start_with? "From " + # }.each { |mail| + # unix_from = mail.shift + # i = mail.index("\n") + # header = mail[0...i] + # body = mail[(i+1)..-1] + # body.pop if body.last == "\n" + # fields = header.slice_before { |line| !" \t".include?(line[0]) }.to_a + # p unix_from + # pp fields + # pp body + # } + # } + # + # # split mails in mbox (slice before Unix From line after an empty line) + # open("mbox") { |f| + # emp = true + # f.slice_before { |line| + # prevemp = emp + # emp = line == "\n" + # prevemp && line.start_with?("From ") + # }.each { |mail| + # mail.pop if mail.last == "\n" + # pp mail + # } + # } + # def slice_before: (untyped pattern) -> ::Enumerator[::Array[Elem], void] | () { (Elem elt) -> boolish } -> ::Enumerator[::Array[Elem], void] end