Ruby each_with_index offset
Actually, Enumerator#with_index
receives offset as an optional parameter:
[:foo, :bar, :baz].to_enum.with_index(1).each do |elem, i|
puts "#{i}: #{elem}"
end
outputs:
1: foo
2: bar
3: baz
BTW, I think it is there only in 1.9.2.
Ruby 1.8.7 each_with_index index offset
try this:
collection[4..-1].each_with_index do |element, index|
#do smth
end
this example will start from fifth element.
Ruby - each starting offset
Another, possibly more direct and readable possibility is to use Array#drop
:
a.drop(3).each do |i|
# do something with item i
end
Now this really shines if combined with other methods inherited from Enumerable
, so chances are there's a better alternative to your imperative each
loop. Say you want to filter the extracted slice and transform it afterwards:
a = [0,1,2,3,4,5,6,7]
a.drop(3).select(&:even?).map { |x| x * 2 }
# => [8, 12]
Or say you want to print a list of all the values:
a = ["1", "2", "3", "4", "5"]
puts a.drop(3).join("\n")
Output:
4
5
These features inherited from functional programming are what makes Ruby so strong :)
using each_with_index and adding values with corresponding index for a new array
You can use map
to accually return the results:
def add_value_and_index(array)
array.map.with_index { |value, index| value + index }
end
If the curriculum isn't using map
yet, you can create a new array and add the sums to that in each iteration:
def add_value_and_index(array)
result = []
array.each_with_index { |value, index| result << value + index }
result
end
I would not use that second example in production, since it is verbose and hard to read.
How to map/collect with index in Ruby?
If you're using ruby 1.8.7 or 1.9, you can use the fact that iterator methods like each_with_index
, when called without a block, return an Enumerator
object, which you can call Enumerable
methods like map
on. So you can do:
arr.each_with_index.map { |x,i| [x, i+2] }
In 1.8.6 you can do:
require 'enumerator'
arr.enum_for(:each_with_index).map { |x,i| [x, i+2] }
Iterate through an array using each_with_index without a separate index variable
You can do:
diag1, diag2 = board.map.with_index {|row, i| [row[i],row[-i-1]]}.transpose
The main trick I'm using here is array's way of interpret negative argument. array[-1]
always means the last element of an array, array[-2]
denotes second last etc.
Ruby : Choosing between each, map, inject, each_with_index and each_with_object
A more tl;dr answer:
How to choose between each, map, inject, each_with_index and each_with_object?
Use
#each
when you want "generic" iteration and don't care about the result. Example - you have numbers, you want to print the absolute value of each individual number:numbers.each { |number| puts number.abs }
Use
#map
when you want a new list, where each element is somehow formed by transforming the original elements. Example - you have numbers, you want to get their squares:numbers.map { |number| number ** 2 }
Use
#inject
when you want to somehow reduce the entire list to one single value. Example - you have numbers, you want to get their sum:numbers.inject(&:+)
Use
#each_with_index
in the same situation as#each
, except you also want the index with each element:numbers.each_with_index { |number, index| puts "Number #{number} is on #{index} position" }
Uses for
#each_with_object
are more limited. The most common case is if you need something similar to#inject
, but want a new collection (as opposed to singular value), which is not a direct mapping of the original. Example - number histogram (frequencies):numbers.each_with_object({}) { |number, histogram| histogram[number] = histogram[number].to_i.next }
Related Topics
How to Check If a Class Is Defined
What Is the Best/How to Validate an Email Address in Ruby
Execute a Rake Task from Within Migration
How to Set the Default String Encoding on Ruby 1.9
How to Get a Date from a Week Number
Rails3 Devise Undefined Method 'Confirmation_Url'
Getting Typed Results from Activerecord Raw SQL
Regex Match Everything Up to First Period
Calculating Difference in Time Between Two Time Objects
Why Is 'Return a or B' a Void Value Expression Error in Ruby
How to Handle Errors with Httparty
How to See the Dependency Tree Just from Gemfile
Case-Insensitive Array#Include
How to Convert PDF Files to Images Using Rmagick and Ruby
Rails Erb Form Helper Options_For_Select :Selected
How to Backreference in Ruby Regular Expression (Regex) with Gsub When I Use Grouping