From: wishdev@...
Date: 2019-12-23T22:12:08+00:00
Subject: [ruby-core:96443] [Ruby master Feature#16446] Enumerable#take_*, Enumerable#drop_* counterparts with positive conditions

Issue #16446 has been updated by wishdev (John Higgins).


sawa (Tsuyoshi Sawada) wrote:
> wishdev (John Higgins) wrote:
> >I prefer simpler examples
> > ary = [-1, 0, 1]
> 
> My intention of including two `0`s in the example was to show that there remains an asymmmetry; the search is done from the left, not from the right. In principle, we can still extend the paradigm, but I am not asking for that.

Nothing wrong with that at all - but I think adding a :reverse options to the methods would accomplish a right to left search feature. 

As I said - declaring what you want to do as opposed to trying to come up with some group of 2 words descriptions seems the wiser path. Especially looking at concepts like reversing the search direction.........

----------------------------------------
Feature #16446: Enumerable#take_*, Enumerable#drop_* counterparts with positive conditions
https://bugs.ruby-lang.org/issues/16446#change-83367

* Author: sawa (Tsuyoshi Sawada)
* Status: Open
* Priority: Normal
* Assignee: 
* Target version: 
----------------------------------------
#16441 led me to think about the issue more generally. When we want to split a series of iterations by the first element that satisfies (or dissatisfies) a condition, we have three factors to consider.

(1) Whether we want the condition to work **negatively** or **positively**
(2) Whether we want the first element to satisfy (or dissatisfy) the condition to be included in the **left** side or the **right** side of the split
(3) Whether we want the **left** side or the **right** side in the returned output

This leads us to eight possible combinations to consider.

```ruby
enum = [1, 1, 0, 3, 3, 0, 5, 5].to_enum
```

| |(1)|(2)|(3)|method|example|
|--|--|--|--|--|--|
|1|negatively|left|left|`take_while`|`enum.foo1(&:nonzero?) # => [1, 1]`|
|2|negatively|left|right|`drop_while`|`enum.foo2(&:nonzero?) # => [0, 3, 3, 0, 5, 5]`|
|3|negatively|right|left||`enum.foo3(&:nonzero?) # => [1, 1, 0]`|
|4|negatively|right|right||`enum.foo4(&:nonzero?) # => [3, 3, 0, 5, 5]`|
|5|positively|left|left||`enum.foo5(&:zero?) # => [1, 1]`|
|6|positively|left|right||`enum.foo6(&:zero?) # => [0, 3, 3, 0, 5, 5]`|
|7|positively|right|left||`enum.foo7(&:zero?) # => [1, 1, 0]`|
|8|positively|right|right||`enum.foo8(&:zero?) # => [3, 3, 0, 5, 5]`|

Proposal #16441 asks for a method that corresponds to case 3 in the table above, but I think that would make the paradigm messy unless case 4 is also implemented. Either cases 3 and 4 should both be implemented, or both not. Actually, the current proposal is not about cases 3 and 4. I would leave that to #16641.

In many use cases (including the first example in #16641), we want to detect the "marker element" by which we split the iterations. In the cases above, that can be the element `0`. In such use cases, it is more natural to describe the condition in positive terms (i.e., `zero?`) rather than negative terms (i.e., `nonzero?`). (And in other use cases, it might be the other way around.) So I would like to propose methods that correspond to cases 5, 6, 7, 8 above.

Naming of the methods should be done systematically. As a candidate, I came up with the following:

||method|
|--|--|
|5|`take_before`|
|6|`drop_before`|
|7|`take_upto`|
|8|`drop_upto`|




-- 
https://bugs.ruby-lang.org/

Unsubscribe: <mailto:ruby-core-request@ruby-lang.org?subject=unsubscribe>
<http://lists.ruby-lang.org/cgi-bin/mailman/options/ruby-core>