Python list comprehension => Ruby select / reject by index, not by element

Given:

arr=[10, 20, 30, 40, 50, 60, 70, 80, 90, 100]
      0   1   2   3   4   5   6   7   8    9    # index of arr

In Python, you can select or reject list items with the index of that item, combining the enumeratesentence ifin a list comprehension:

Each item except the third:

>>> [e for i,e in enumerate(arr) if i%3]
[20, 30, 50, 60, 80, 90]

Every third item in the list:

>>> [e for i,e in enumerate(arr) if not i%3]
[10, 40, 70, 100]

Or, even simpler, with a snippet:

>>> arr[::3]
[10, 40, 70, 100]   

In Ruby with us . select and . reject

> arr.each_with_index.reject { |e,i| i%3==0 }
=> [[20, 1], [30, 2], [50, 4], [60, 5], [80, 7], [90, 8]]
> arr.each_with_index.select { |e,i| i%3==0 }
=> [[10, 0], [40, 3], [70, 6], [100, 9]]

And then apply . collect to this:

> arr.each_with_index.select { |e,i| i%3==0 }.collect{|e,i| e}
=> [10, 40, 70, 100]

For a slice, the rough Ruby equivalent might be:

> (0..arr.length).step(3).each { |e| p arr[e] }
10
40
70
100
=> 0..10

But I can't figure out how to put these socks into a new array, different from:

> new_arr=[]
=> []
> (0..arr.length).step(3).each { |e| new_arr.push(arr[e]) }
=> 0..10
> new_arr
=> [10, 40, 70, 100]

Questions:

  • Are they the best Ruby idioms for what I'm trying to do (.select or .reject with .collect)?
  • Is there a way to do something in this direction with a slice
     new_arr=(0..arr.length).step(3).each { |e| arr[e] }.some_method:?
+4
3

:

arr.each_with_index.select { |e, i| i % 3 == 0 }
#=> [[10, 0], [40, 3], [70, 6], [100, 9]]

arr.select.each_with_index { |e, i| i % 3 == 0 }
#=> [10, 40, 70, 100]

select , Enumerator#with_index:

arr.select.with_index { |e, i| i % 3 == 0 }
#=> [10, 40, 70, 100]

, map ( collect) :

(0..arr.length).step(3).map { |e| arr[e] }
#=> [10, 40, 70, 100]

values_at :

arr.values_at(*(0..arr.length).step(3))
#=> [10, 40, 70, 100]

* ( to_a), , :

arr.values_at(*(0..arr.length).step(3))
arr.values_at(*(0..arr.length).step(3).to_a)
arr.values_at(*[0, 3, 6, 9])
arr.values_at(0, 3, 6, 9)

:

arr.values_at(*0.step(arr.size, 3))
#=> [10, 40, 70, 100]
+6

each_slice arr " ", each_slice(3):

p arr.each_slice(3).to_a
# => [[10, 20, 30], [40, 50, 60], [70, 80, 90], [100]]

, , , , , map :

arr = [10, 20, 30, 40, 50, 60, 70, 80, 90, 100]
p arr.each_slice(3).map(&:first)
# => [10, 40, 70, 100]

.map{|e| e.first} .map{|e| e[0]}, .map(&:first).

+3

β€œBut I can’t understand how to assemble them into a new array other than (...)” There is a method that does this, and you found its name, formulating your question:

arr=[10, 20, 30, 40, 50, 60, 70, 80, 90, 100]
new_arr = (0..arr.length).step(3).collect { |e|  arr[e] }

collect has an alias: map.

+1
source

Source: https://habr.com/ru/post/1680654/


All Articles