【问题标题】:Not able to create an ('A'..'Z') initialised hash in ruby class? Why?无法在 ruby​​ 类中创建 ('A'..'Z') 初始化哈希?为什么?
【发布时间】:2017-06-02 13:20:02
【问题描述】:

我想创建一个哈希,另一方面,它用字母 'A'..'Z'"" 初始化。

abcliste = {}
('A'..'Z').to_a.each { |letter| abcliste[letter] = ""}
print abcliste # => {"A"=>"", "B"=>"", "C"=>"", ... , "Z"=>""}

但是,如果我使用一个类,同样的代码,我会得到一个数组["A", "B", "C", "D", "E", ... , "Z"]

class Abcliste
  def initialize
    @abcliste = {}
    @abcliste = ('A'..'Z').to_a.each { |letter| @abcliste.store(letter, "") }
    print @abcliste # => ["A", "B", "C", "D", "E", ... , "Z"]
  end
end

a = Abcliste.new # => ["A", "B", "C", "D", "E", ... , "Z"]
  1. 为什么会这样?
  2. 如何编写一个类,以便从 ('A'..'Z') 生成哈希

【问题讨论】:

  • " 如果我​​使用一个类,使用 相同的代码" – 这里有一个提示:它不是相同的代码。比较差异,你会发现错误。

标签: arrays ruby class hash


【解决方案1】:

这是您的代码中发生的情况

@abcliste = {}
@abcliste = ('A'..'Z').to_a.each { |letter| @abcliste[letter] = "" }

事情是按这个顺序发生的

  • 您创建{} 并分配给@abcliste
  • 您使用each 循环将所有值存储在哈希中
  • @abcliste 现在的值是正确的,但是……
  • 您将each 的返回值分配给@abcliste — 哦哦!

当你执行array.each { ... }时,each的返回值就是数组array

【讨论】:

    【解决方案2】:

    首先,I think it is bad practice to use object initialization to do more than load data into a newly create instance。如果您只想传递一个函数,那么您应该使用模块而不是类。

    module Abcliste
      def self.for(range, content = '')
        range.each_with_object({}){|element, hash| hash[element] = content}
      end
    end
    
    puts Abcliste.for 'A'..'Z'
    

    将输出:

    {"A"=>"", "B"=>"", "C"=>"", "D"=>"", "E"=>"", "F"=>" ", "G"=>"", "H"=>"", "I"=>"", "J"=>"", "K"=>"", "L"=>"", "M"=>"", "N "=>"", "O"=>""、"P"=>""、"Q"=>""、"R"=>""、"S"=>""、"T"=>""、"U "=>"", "V"=>"", "W"=>"", "X"=>"", "Y"=>"", "Z"=>""}

    这段代码也可以让你这样做:

    puts Abcliste.for 1..10, 'foo'
    

    {1=>"foo", 2=>"foo", 3=>"foo", 4=>"foo", 5=>"foo", 6=>"foo", 7=>"富”, 8=>"foo", 9=>"foo", 10=>"foo"}

    【讨论】:

    • 注意:如果你需要在你的inject中每次都返回hash,你需要each_with_object
    • 好点 - 虽然你需要小心each_with_object stackoverflow.com/a/19064234/1014251
    • 是的 - 我正要更新我的答案以表明这一点。我只是想补充一下injecteach_with_object 之间的区别。我应该更新,然后发表评论。
    【解决方案3】:

    尝试关注。

    class Abcliste
      def initialize
        @abcliste = {}
        ('A'..'Z').to_a.each { |letter| @abcliste.store(letter, "") }
        print @abcliste
      end
    end
    
    a = Abcliste.new 
    

    输出:

    {"A"=>"", "B"=>"", "C"=>"", "D"=>"", "E"=>"", "F"=>"", "G"=>"", "H"=>"", "I"=>"", "J"=>"", "K"=>"", "L"=>"", "M"=>"", "N"=>"", "O"=>"", "P"=>"", "Q"=>"", "R"=>"", "S"=>"", "T"=>"", "U"=>"", "V"=>"", "W"=>"", "X"=>"", "Y"=>"", "Z"=>""} => #<Abcliste:0x888f9d4 @abcliste={"A"=>"", "B"=>"", "C"=>"", "D"=>"", "E"=>"", "F"=>"", "G"=>"", "H"=>"", "I"=>"", "J"=>"", "K"=>"", "L"=>"", "M"=>"", "N"=>"", "O"=>"", "P"=>"", "Q"=>"", "R"=>"", "S"=>"", "T"=>"", "U"=>"", "V"=>"", "W"=>"", "X"=>"", "Y"=>"", "Z"=>""}
    

    【讨论】:

      【解决方案4】:

      您的代码

      你不需要to_a,你不应该覆盖@abcliste:

      @abcliste = {}
      ('A'..'Z').each{ |letter| @abcliste.store(letter,"")}
      print @abcliste
      

      替代方案

      each_with_object

      上面的代码可以用each_with_object缩短:

      @abcliste = ('A'..'Z').each_with_object({}) { |letter, liste| liste.store(letter,"") }
      

      地图

      ('A'..'Z').map{|letter| [letter, ""] }.to_h
      #=> {"A"=>"", "B"=>"", "C"=>"", "D"=>"", "E"=>"", "F"=>"", "G"=>"", "H"=>"", "I"=>"", "J"=>"", "K"=>"", "L"=>"", "M"=>"", "N"=>"", "O"=>"", "P"=>"", "Q"=>"", "R"=>"", "S"=>"", "T"=>"", "U"=>"", "V"=>"", "W"=>"", "X"=>"", "Y"=>"", "Z"=>""}
      

      它首先创建一个数组对(字母和“”),并将其转换为哈希。

      默认散列

      另一种可能性是只定义一个带有默认值的哈希:

      @abcliste = Hash.new{|h,k| h[k] = "" }
      p @abcliste
      #=> {}
      @abcliste["A"] << 'letters'
      p @abcliste["A"]
      #=> "letters"
      p @abcliste["B"]
      #=> ""
      

      【讨论】:

      • ('A'..'Z').zip([""]*('A'..'Z').count).to_h
      • @mudasobwa:谢谢。我虽然是这样,但 zip 在这里没有意义,恕我直言。
      • @mudasobwa 精美优雅!您甚至可以将其缩短为 ('a'..'z').zip(['']).to_h
      【解决方案5】:

      问题是#each 将返回您迭代的数组。因此,在您将其分配给 @abcliste 之后,所有 #store 调用都无关紧要,因为您已经完全替换了实例变量的值。

      删除第二个作业。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2012-03-20
        • 2016-01-27
        • 2010-10-19
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多