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, one can select or reject elements of a list given the index of that element by combining enumerate and an if clause in a list comprehension:
Every item except the third:
>>> [e for i,e in enumerate(arr) if i%3]
[20, 30, 50, 60, 80, 90]
Every third item in a list:
>>> [e for i,e in enumerate(arr) if not i%3]
[10, 40, 70, 100]
Or, even easier, with a slice:
>>> arr[::3]
[10, 40, 70, 100]
In Ruby, we have .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 that:
> arr.each_with_index.select { |e,i| i%3==0 }.collect{|e,i| e}
=> [10, 40, 70, 100]
For the 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 toe collect those into a new array other than:
> new_arr=[]
=> []
> (0..arr.length).step(3).each { |e| new_arr.push(arr[e]) }
=> 0..10
> new_arr
=> [10, 40, 70, 100]
Questions:
- Are these the best Ruby idioms for what I am trying to do (.select or .reject with .collect)?
- Is there a way to do something along these lines with a slice:
new_arr=(0..arr.length).step(3).each { |e| arr[e] }.some_method?