TypeError:无法将String转换为Integer

dem*_*mas 5 ruby

我有代码:

class Scene
  def initialize(number)
    @number = number
  end
  attr_reader :number
end

scenes = [Scene.new("one"), Scene.new("one"), Scene.new("two"), Scene.new("one")]

groups = scenes.inject({}) do |new_hash, scene|
   new_hash[scene.number] = [] if new_hash[scene.number].nil?
   new_hash[scene.number] << scene
end
Run Code Online (Sandbox Code Playgroud)

当我发起它时,我得到错误:

freq.rb:11:in `[]': can't convert String into Integer (TypeError)
       from freq.rb:11:in `block in <main>'
       from freq.rb:10:in `each'
       from freq.rb:10:in `inject'
       from freq.rb:10:in `<main>'
Run Code Online (Sandbox Code Playgroud)

如果我将场景更改为:

scenes = [Scene.new(1), Scene.new(1), Scene.new(2), Scene.new(1)]
Run Code Online (Sandbox Code Playgroud)

问题消失了.

为什么我在第一种情况下收到错误消息?为什么Ruby决定将scene.number从String转换为Integer?

还有一个关于'注入'方法的问题.当Ruby初始化'new_hash'变量时,Ruby如何知道这个变量的类型?

the*_*Man 10

尝试:

groups = scenes.inject({}) do |new_hash, scene|
   new_hash[scene.number] = [] if new_hash[scene.number].nil?
   new_hash[scene.number] << scene
   new_hash
end

Ruby将传递给inject()的空哈希值设置为new_hash.当块结束时,返回值用于在下一次通过时初始化new_hash,即new_hash继续累积块的结果.

在您的原始代码中,您没有返回散列但是数组(new_hash [scene.number]是一个数组)并且下一个循环通过Ruby抱怨,因为new_hash [scene.number]试图用字符串查找数组价值,因此你得到的错误.


小智 6

ZED是对的.参见Jay Fields的思考:Ruby:inject通过例子注入一个很好的解释.

如图所示,您的块返回一个数组.所以new_hashin |new_hash, scene|最终成为那个数组.当Ruby尝试查找数组索引'one'时,它会抛出错误,因为'one'是String而不是Integer.

所有你需要做的就是返回new_hashZED显示,你会得到这样的东西:

{
  "two" => [
    #<Scene:0x101836470 @number="two">
  ],
  "one" => [
    #<Scene:0x101836510 @number="one">,
    #<Scene:0x1018364c0 @number="one">,
    #<Scene:0x101836420 @number="one">
  ]
}
Run Code Online (Sandbox Code Playgroud)