0

I want to translate these 2 for-loops to a loop with a block, but I keep on getting a Type error.

This is the original code: EDIT I have added what h1 and h2 are

h1 = gethashfromfile('arrtime.txt')
h2 = gethashfromfile('deptime.txt')
k1 = h1.keys
k2 = h2.keys
kcommon = k1 & k2
k_not_in_both = (k1 - kcommon) | (k2 - kcommon)

arr = kcommon.to_a

for i in 0...arr.size
 stay = h2[arr[i]] - h1[arr[i]]
 if stay < 0
   puts arr[i] + ': data issue'
 else
   puts arr[i] + ': stay ' + stay.to_s + ' minutes'
 end
end

arr2 = k_not_in_both.to_a
for i in 0...arr2.size
puts arr2[i] + ': data issue'
end

This is what I have so far:

arr.each do |i|
  stay = h2[arr[i]] - h1[arr[i]]
  if stay < 0
      puts arr[i] + ': data issue'
  else
      puts arr[i] + ': stay' + stay.to_s + ' minutes'
  end
end

arr2 = k_not_in_both.to_a
arr2.each { |x| puts arr2[x] + ': data issue'}

This is the error I am receiving:

 TypeError: no implicit conversion of String into Integer
    from (irb#1):202:in `[]'
    from (irb#1):202:in `block in irb_binding'
    from (irb#1):201:in `each'
    from (irb#1):201
4
  • You have not defined what h1 and h2 are or really what the desired result is. While you may get help understanding loops, us understanding the actual problem you are facing will lead to more constructive idiomatic answers in general Commented Jan 26, 2017 at 14:10
  • Note that in ruby, for loops and each loops get interpreted in exactly the same way by the interpreter. Somehow that has led to the convention that we should only use each (each is the internal name for these loops in MRI). So your question isn't really about translating a for loop into an each, but how to rewrite it in more idiomatic ruby :-) Commented Jan 26, 2017 at 15:19
  • @niels not correct, for loops are different. They don't create a local scope, and that is why we prefer each loops in Ruby! Commented Jan 26, 2017 at 19:01
  • you are so right! Must have made that up... Commented Jan 26, 2017 at 19:19

1 Answer 1

3
arr.each do |i|
  # do something with i
end

i isn't an index, it's the element itself!

You can replace arr[i] by just i.

To avoid making this mistake, you could use more descriptive variable names :

letters = ['a', 'b', 'c']
letters.each do |letter|
  puts letter
end
# =>
# a
# b
# c

letters[letter] would throw an error, because letters is an array and array[] expects an integer as index, not a string.

Sign up to request clarification or add additional context in comments.

2 Comments

should we mention each_with_index here? probably not. :)
@SergioTulentsev then we definitely shouldn't mention each_index at all

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.