array collect - nil can't be coerced into Float (TypeError)

J

Jason Lillywhite

I have this simple program that has a problem that I just can't find a
solution to:
***********
class MyArray

def count
a = [50.1,52.0,55.0,60.0]
b = [0.24,0.1,0.29,0.9]
i = 0
c = []
while i <= 4 do
puts c = b.collect {|x| x * a}
i += 1
end

end
end

number = MyArray.new
number.count
*********
I want each element of array 'b' to be multiplied by each element of 'a'
and return a vector, 'c' with 16 rows.

this code works, but I get an error that says:
ArrayInsert.rb:9:in `*': nil can't be coerced into Float (TypeError)
from ArrayInsert.rb:9:in `count'
from ArrayInsert.rb:9:in `collect'
from ArrayInsert.rb:9:in `count'
from ArrayInsert.rb:17

I don't understand where 'nil' is coming from. Can someone help me with
this one? Thank you.
 
S

Stefano Crocco

I have this simple program that has a problem that I just can't find a
solution to:
***********
class MyArray

def count
a = [50.1,52.0,55.0,60.0]
b = [0.24,0.1,0.29,0.9]
i = 0
c = []
while i <= 4 do
puts c = b.collect {|x| x * a}
i += 1
end

end
end

number = MyArray.new
number.count
*********
I want each element of array 'b' to be multiplied by each element of 'a'
and return a vector, 'c' with 16 rows.

this code works, but I get an error that says:
ArrayInsert.rb:9:in `*': nil can't be coerced into Float (TypeError)
from ArrayInsert.rb:9:in `count'
from ArrayInsert.rb:9:in `collect'
from ArrayInsert.rb:9:in `count'
from ArrayInsert.rb:17

I don't understand where 'nil' is coming from. Can someone help me with
this one? Thank you.


Array indexes go from 0 to the number of elements of the array minus one. In
your code, you allow i to be 4 (because you put <= in the while condition),
then use i to access the elements of the array a. Since a has four elements,
the last non-nil element has index 3. When i is 4, a will return nil,
giving the error you see.

I hope this helps

Stefano
 
R

Robert Dober

I have this simple program that has a problem that I just can't find a
solution to:
***********
class MyArray

def count
a = [50.1,52.0,55.0,60.0]
b = [0.24,0.1,0.29,0.9]
i = 0
c = []
while i <= 4 do

this should be i < 4, however ....
puts c = b.collect {|x| x * a}
i += 1
end

end
end

I don't understand where 'nil' is coming from. Can someone help me with
this one? Thank you.

I'd rather do this like this

c = a.zip(b).map{ |a_ele, b_ele| a_ele * b_ele }

this will still give an error if b is shorter than a (but in Ruby1.9 a
will be cut IIRC).

HTH
Robert
 
J

Jason Lillywhite

I will settle with this:

class MyArray
def count
a = [1,2,3]
b = [0.5,0.25]
num = a.length
i = 0
c = []
while i < num do
c << b.collect {|x| x * a}
i += 1
end
puts c
end
end

number = MyArray.new
number.count


that way it does matter if I change the length of a.

thanks again.
 
S

Stefano Crocco

I will settle with this:

class MyArray
def count
a = [1,2,3]
b = [0.5,0.25]
num = a.length
i = 0
c = []
while i < num do
c << b.collect {|x| x * a}
i += 1
end
puts c
end
end

number = MyArray.new
number.count


that way it does matter if I change the length of a.

thanks again.


You don't need num. You can directly write:

while i < a.length
...

A much better alternative is:

a.each do |it|
c << b.collect{|x| x * it}
end

a.each passes each element of a, in turn, as argument to the block. Each time
the block is called, it calls b.collect, multiplying the elements of b for the
current element of a.

An even more elegant way to do this is to use inject (see ri Enumerable#inject
for an explanation of how it works):

a = [1,2,3]
b = [0.5,0.25]
c = a.inject([]) do |res, i|
res << b.collect{|x| x*i}
end

Stefano
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,733
Messages
2,569,439
Members
44,829
Latest member
PIXThurman

Latest Threads

Top