`[]': no implicit conversion of String into Integer (TypeError)

Clyde Brown picture Clyde Brown · May 3, 2017 · Viewed 8.5k times · Source

I seem to be getting a type error in the following code:

    def can_cast(hand, *spell_cost)
      colored_mana_hand = Array.new
      colored_mana_cost_aggregate = Array.new
      colored_mana_spent = Array.new
      colorless_mana_hand = 0
      colorless_mana_cost_aggregate = 0

      hand_array = hand.split("").sort
      total_cost = spell_cost.join.split("").sort   

      hand_array.each do |i|
      if hand_array[i].to_i != 0                       
        colorless_mana_hand += hand_array[i].to_i
      else
        colored_mana_hand << hand_array[i]
      end
    end

    total_cost.each do |i|                 
      if total_cost[i].to_i != 0                  
        colorless_mana_cost_aggregate += total_cost[i].to_i
      else
        colored_mana_cost_aggregate << total_cost[i]
      end
    end

colored_mana_cost_aggregate.each do |i|                                                
  if colored_mana_hand.include?(colored_mana_cost_aggregate[i])
     colored_mana_spent << colored_mana_cost_aggregate[i]           
colored_mana_hand.rotate(colored_mana_hand.index(colored_mana_cost_aggregate[i])).shift
  end
end

   colored_mana_spent == colored_mana_cost_aggregate && (colored_mana_hand.length + colorless_mana_hand) >= colorless_mana_cost_aggregate 
   end

It looks like this

   `[]': no implicit conversion of String into Integer (TypeError)

Could Anyone help me?

I think I'm using an array as an integer, but I can't see where that might be possible.

Answer

SteveTurczyn picture SteveTurczyn · May 3, 2017

As Brian says, you're misinterpreting how the each works with the block parameter

Instead of

hand_array.each do |i|
  if hand_array[i].to_i != 0                       
    colorless_mana_hand += hand_array[i].to_i
  else
    colored_mana_hand << hand_array[i]
  end
end

You just reference the element

hand_array.each do |hand|
  if hand.to_i != 0                       
    colorless_mana_hand += hand.to_i
  else
    colored_mana_hand << hand
  end
end

If you actually want the index of the array, you can use each_with_index

hand_array.each_with_index do |_hand, i|
  if hand_array[i].to_i != 0                       
    colorless_mana_hand += hand_array[i].to_i
  else
    colored_mana_hand << hand_array[i]
  end
end

or just use a range of index values

(0...hand_array.count).each do |i|
  if hand_array[i].to_i != 0                       
    colorless_mana_hand += hand_array[i].to_i
  else
    colored_mana_hand << hand_array[i]
  end
end

As to exactly what the error means... if the hand_array contains strings such as "7" then i contains "7" and you're trying to access hand_array["7"] ... in other words trying to access an array element using a string instead of an integer. And Ruby won't automatically (implicitly) convert a string into an integer for an array index.