Andy - 1 year ago 67
Ruby Question

# Method that returns the first n odd numbers

Just a quick question -- I'm probably overlooking something here.

The below method outputs the first 2 odd numbers correctly: [1,3]

If I'm not mistaken, shouldn't I want the length of the array to eventually equal n? As I understand it, the length of the outputted array [1,3] is 2, which also represent the first n-many odds: 2.

As such, the comparison in line 6 would now be <= rather than <

However, if I do that, first_n_odds(2) would now equal [1,3,5], which gives me the first three odds. What's going on here?

Thanks!

``````def first_n_odds(n)

array = []
current_number = 0

while array.length < n
if current_number % 2 == 1
array << current_number
end
current_number += 1
end

return array

end

puts first_n_odds(2)       # output is [1,3]
``````

Let's do your example with `n == 2`.

Iteration 1: `array.length == 0`. Iteration 2: `array.length == 1`.

Both of these values are `< 2`. Now if you change `<` to `<=`, you'd have a 3rd iteration where `array.length == 2` since your check happens before adding the new element to the array.

Since you seem to be fairly new to Ruby, here are some ways to define the method in a more idiomatic way:

``````# Mapping over a range
def first_n_odds_1(n)
(0...n).map { |x| x * 2 + 1 }
end

# Mapping over an Enumerator
def first_n_odds_2(n)
n.times.map { |x| x * 2 + 1}
end

# Using Numeric#step + Enumerable#take
def first_n_odds_3(n)
1.step(Float::INFINITY, 2).take(n)
end

# A more explicit version of the previous method
def first_n_oods_4(n)
1.step(by: 2, to: Float::INFINITY).take(n)
end
``````
Recommended from our users: Dynamic Network Monitoring from WhatsUp Gold from IPSwitch. Free Download