From: zverok.offline@... Date: 2020-04-25T17:48:41+00:00 Subject: [ruby-core:98065] [Ruby master Feature#16812] Allow slicing arrays with ArithmeticSequence Issue #16812 has been updated by zverok (Victor Shepelev). As there is no immediate rejection, I updated the implementation, making it more robust. @Dan0042, I tried to make edge cases consistent, so now they are... ```ruby (0..20).to_a[10.step(by: -2)] # => [10, 8, 6, 4, 2, 0] -- avoids weird cycling (0..20).to_a[(-5..5) % 2] # => [] -- this is consistent with (0..20).to_a[-5..5] # which can be thought as (-5..5) % 1 # => [] # Note, though: (0..20).to_a[-19..5] # => [2, 3, 4, 5] -- not literally "from -19 to 5", but "from 19th from the end to 5th from the beginning" # ...so... (0..20).to_a[(-19..5)%2] # => [2, 4] ``` @nobu I've tried to fix bugs. Now float begin/end is processed correctly, float step is TypeError, and the code does not rely on `#take_while`/`#drop_while`. @mrkn I've checked against Python impl, and believe the behavior is mostly the same. One difference I am aware of is this: Python: ```python list(range(10))[-100:100:2] #=> [0, 2, 4, 6, 8] ``` Ruby: ```ruby [*0..10][(-100..100)%2] # => nil ``` That's because first of all I wanted to make it consistent with ```ruby [*0..10][-100..100] # => nil ``` ...which may be questioned (like, "range from -100 to 100 includes 0..10, so it should fetch entire array"), but that's how it is now :) ---------------------------------------- Feature #16812: Allow slicing arrays with ArithmeticSequence https://bugs.ruby-lang.org/issues/16812#change-85291 * Author: zverok (Victor Shepelev) * Status: Assigned * Priority: Normal * Assignee: matz (Yukihiro Matsumoto) ---------------------------------------- I believe when concepts of ArithmeticSequence and `Range#%` were introduced, one of the main intended usages was array slicing in scientific data processing. So, it seems to make sense to allow this in `Array#[]`: ```ruby ary[(5..20) % 2] # each second element between 5 and 20 ary[(0..) % 3] # each third element ary[10.step(by: -1)] # elements 10, 9, 8, 7 .... ``` PR is [here](https://github.com/ruby/ruby/pull/3055). My reasoning is as follows: 1. As stated above, ArithmeticSequence and `Range#%` seem to have been introduced exactly for this goal 2. Python has its slicing syntax as `begin:end:step` (with a possibility to omit either), and it seems to be well respected and used feature for data processing. So I believe it is useful, and relatively easy to integrate into existing functionality I expect the usual "it is ugly and unreadable!" backlash. I don't have an incentive, nor energy, to "defend" the proposal, so I would not. -- https://bugs.ruby-lang.org/ Unsubscribe: