Rubin select by index

I am trying to select elements from an array:

arr = ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n'] 

whose index is the Fibonacci number. I want to get the result:

 ['a', 'b', 'c', 'd', 'f', 'i', 'n'] 

My code returns both an element and an index.

 def is_fibonacci?(i, x = 1, y = 0) return true if i == x || i == 0 return false if x > i is_fibonacci?(i, x + y, x) end arr.each_with_index.select do |val, index| is_fibonacci?(index) end 

This code returns:

 [["a", 0], ["b", 1], ["c", 2], ["d", 3], ["f", 5], ["i", 8], ["n", 13]] 

Please help me understand how I can still iterate over an array and evaluate an index, but only return it.

+5
source share
3 answers

You can change the last bit of your code to

 arr.select.with_index do |val, index| is_fibonacci?(index) end 

This works because if you call a method such as select without a block, you get an Enumerator object on which you can then link more Enumerable methods.

In this case, I used with_index , which is very similar to calling each_with_index in the original array. However, since this happens after select instead of the previous one, select returns elements from the original array without added indices

+12
source

Your code seems wonderful so far, I would not change it. You can view your results after the fact and change the [element, index] pairs to contain an element display for each pair and accept only first :

 >> results = [["a", 0], ["b", 1], ["c", 2], ["d", 3], ["f", 5], ["i", 8], ["n", 13]] >> results.map(&:first) => ["a", "b", "c", "d", "f", "i", "n"] 
+1
source

Here is another way to do it.

 index_gen = Enumerator.new do |y| i = 0 j = 1 loop do y.yield i unless i==j i, j = j, i + j end end #=> #<Enumerator: #<Enumerator::Generator:0x007fa3eb979028>:each> arr.values_at(*index_gen.take_while { |n| n < arr.size }) #=> ["a", "b", "c", "d", "f", "i", "n"] 

or

 index_gen.take_while { |n| n < arr.size }.map { |n| arr[n] } #=> ["a", "b", "c", "d", "f", "i", "n"] 

Note:

  • I suggested that Fibonacci numbers start from zero (not one), which is a modern definition.
  • The Fibonacci sequence starts at 0, 1, 1, 2,... Building a counter index_gen skips the second 1 .
  • index_gen.take_while { |n| n < arr.size } #=> [0, 1, 2, 3, 5, 8, 13]
0
source

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


All Articles