From: halostatue@... Date: 2020-12-11T03:38:22+00:00 Subject: [ruby-core:101409] [Ruby master Feature#17333] Enumerable#many? Issue #17333 has been updated by austin (Austin Ziegler). Like Daniel in #note-10 and Sawa in #note-6, I don���t think that this is a great choice, although `many?` is surprisingly complex to implement efficiently. The simplest Ruby implementation I could come up with is this: ```ruby def many? reduce(false) { |f, v| vp = block_given? ? yield v : v break true if f && vp vp } end ``` It���s probably a little less efficient than the ActiveSupport extension (which uses two different branches for `block_given?` or not). Something similar was recently suggested to the Elixir core list, and what was decided there is I think a little more generalizable, `count_until` (https://github.com/elixir-lang/elixir/pull/10532). Here���s a Ruby implementation of what could be Enumerable#count_until? ```ruby def count_until(limit, match = nil, &block) cnt = 0 if match warn 'warning: given block not used' if block block = ->(v) { v == match } elsif !block return [limit, count].min if respond_to?(:size) block = ->(_) { true } end stop_at = limit - 1 reduce(0) { |c, v| c += 1 if block.(v) break limit if c == stop_at c } end # (1..20).count_until(5) # => 5 # (1..20).count_until(50) # => 20 # (1..10).count_until(10) == 10 # => true # At least 10 # (1..11).count_until(10) == 10 # => true # At least 10 # (1..11).count_until(10 + 1) > 10 # => true # More than 10 # (1..5).count_until(10) < 10 # => true # Less than 10 # (1..10).count_until(10 + 1) == 10 # => true # Exactly ten ``` This could be easily implemented as `count(until: 10)` or `count(2, until: 10)` or `count(match: 2, until: 10)` instead of a different method entirely. (Sorry if this ends up showing up twice; I sent it first by email, but it appears that my email never made it.) ---------------------------------------- Feature #17333: Enumerable#many? https://bugs.ruby-lang.org/issues/17333#change-89171 * Author: okuramasafumi (Masafumi OKURA) * Status: Open * Priority: Normal ---------------------------------------- `Enumerable#many?` method is implemented in ActiveSupport. https://api.rubyonrails.org/classes/Enumerable.html#method-i-many-3F However, it's slightly different from Ruby's core methods such as `one?` or `all?`, where they take pattern argument. I believe these methods should behave the same so that it's easier to guess and learn. We already have `none?`, `one?`, `any?` and `all?`, which translate into `== 0`, `== 1`, `> 0` and `== self.size`. `many?` method translates into `> 1`, which is reasonable to exist. Currently we need to write something this: ```ruby [1, 2, 3].count(&:odd?) > 1 ``` With `many?`, we can make it simpler: ```ruby [1, 2, 3].many?(&:odd?) ``` Pull Request on GitHub is available at https://github.com/ruby/ruby/pull/3785 -- https://bugs.ruby-lang.org/ Unsubscribe: