Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Return iterating object and index while iterating

Tags:

ruby

array = [1,2,3,{:name => "Peter"}, "hello"]
array.each do |element| # it can be "inject", "map" or other iterators
  # How to return object "array" and position of "element"
  # also next and priviouse "element"
end

of course I can return index by array.index[element] but I am searching for more natural solution. Like proxy_owner in Rails associations

Ruby 1.8.7

What I want to output? I want to return object wich I iterating (array in my case), also number of iteration (index in case of each_with_index)next and priviouse element of iteration.

As input I have got an Array and iterator (each, map, inject etc)

like image 419
fl00r Avatar asked Dec 02 '22 02:12

fl00r


1 Answers

Use Enumerable#each_cons. The following is a copy from ruby1.8.7 rdoc. It should work on ruby 1.8.7.


  • each_cons(n) {...}
  • each_cons(n)

Iterates the given block for each array of consecutive elements. If no block is given, returns an enumerator.


With this , you can give an array:

['a', 'b', 'c', 'd', 'e'].each_cons(3).to_a

# => ["a", "b", "c"], ["b", "c", "d"], ["c", "d", "e"]]

or do:

['a', 'b', 'c', 'd', 'e'].each_cons(3) {|previous, current, nekst|
    puts "#{previous} - #{current} - #{nekst}"
}

# => a - b - c
# => b - c - d
# => c - d - e

If you want indice,

['a', 'b', 'c', 'd', 'e'].each_cons(3).to_a.each_with_index {|(previous, current, nekst), i|
    puts "#{i + 1}. #{previous} - #{current} - #{nekst}"
}

# => 1. a - b - c
# => 2. b - c - d
# => 3. c - d - e

You can pass the array to other enumerators quite generally, for example, with inject:

['a', 'b', 'c', 'd', 'e'].each_cons(3).to_a.inject(''){|str, (previous, current, nekst)|
    str << previous+current+nekst
}

# => "abcbcdcde"
like image 149
sawa Avatar answered Jan 20 '23 13:01

sawa