【问题标题】:Convert Ruby Array into Hash by Looping Through通过循环将 Ruby 数组转换为哈希
【发布时间】:2016-02-28 09:40:27
【问题描述】:

我正在尝试通过迭代将数组转换为哈希。我有以下数组:

weekdays = [["Monday",2],["Tuesday",4],["Thursday",5]]

我正在遍历数组以创建一个像这样的哈希:

hash_weekdays = Hash.new
weekdays.each do |item|
  hash_weekdays["weekday"] = item[0]
  hash_weekdays["number"] = item[1]
end

但是,这仅显示最后一个工作日。关于从这里去哪里的任何想法?谢谢!

【问题讨论】:

    标签: arrays ruby json hash


    【解决方案1】:

    散列包含键值对。每个键仅引用一个值,并且每个键在哈希中都是唯一的。每次迭代都会覆盖您的键 weekdaynumber 的值。这就是为什么你只得到最后一次迭代的结果的原因。

    您可以将其转换为哈希数组作为替代方案。

    weekdays.map{|day, number| {weekday:day, number: number}}
    # => [{:weekday=>"Monday", :number=>2}, {:weekday=>"Tuesday", :number=>4}, {:weekday=>"Thursday", :number=>5}]
    

    如果您的工作日或数字在主数组中是唯一的,您可以使用其中一种作为键,另一种作为哈希值。

    weekdays.to_h
    # => {"Monday"=>2, "Tuesday"=>4, "Thursday"=>5}
    

    weekdays.to_h.invert
    # => {2=>"Monday", 4=>"Tuesday", 5=>"Thursday"}
    

    【讨论】:

    • 感谢@guitarman 的解释,有没有办法修改我的weekdays.each 循环来克服这个问题?
    【解决方案2】:

    你可以这样做:

    weekdays.to_h #=> {"Monday"=>2, "Tuesday"=>4, "Thursday"=>5}
    

    或修复您的代码:

    weekdays = [["Monday",2],["Tuesday",4],["Thursday",5]]
    
    hash_weekdays = Hash.new
    weekdays.each do |item|
      hash_weekdays[item[0]] = item[1]
    end
    
    p hash_weekdays #=> {"Monday"=>2, "Tuesday"=>4, "Thursday"=>5}
    

    【讨论】:

      【解决方案3】:

      您需要将代码更改为以下内容:

      hash_weekdays = Hash.new
      weekdays.each do |item|
        hash_weekdays[item[0]] = item[1]
      end
      hash_weekdays
       #=> {"Monday"=>2, "Tuesday"=>4, "Thursday"=>5} 
      

      weekdays["Monday",2])的第一个元素被传递给块时,块变量被赋值:

      item = ["Monday",2]
      

      由于您需要引用item 的每个元素,因此通常使用两个块变量,其值通过并行赋值(又名多重赋值)进行赋值:

      day, nbr = ["Monday",2]
          #=> ["Monday", 2] 
      day #=> "Monday" 
      nbr #=> 2 
      

      这让你可以写

      hash_weekdays = {} # the more common way of writing hash_weekdays = Hash.new
      weekdays.each { |day, nbr| hash_weekdays[day] = nbr } # used {...} rather than do..end
      hash_weekdays
      

      这可以说是更清楚了。

      请注意,您首先将hash_weekdays 初始化为一个空哈希,然后如果您希望获得哈希的新值(例如,作为方法的最后一行),则需要在末尾添加hash_weekdays 行。您可以使用Enumerable#each_with_object 方法将其简化为一行(非常类似于 Ruby):

      weekdays.each_with_object({}) { |item, hash_weekdays| hash_weekdays[item[0]] = item[1] }
        #=> {"Monday"=>2, "Tuesday"=>4, "Thursday"=>5} 
      

      请注意,这使用并行分配。传递给块的第一个元素 [["Monday", 2], {}] 分配如下:

      item, hash_weekdays = weekdays.each_with_object({}).next
        #=> [["Monday", 2], {}]
      item
        #=> ["Monday", 2] 
      hash_weekdays
        #=> {} 
      

      Ruby 的方式是以稍微复杂的方式使用并行赋值:

      weekdays.each_with_object({}) { |(day, nbr), hash_weekdays|
        hash_weekdays[day] = nbr }
        #=> {"Monday"=>2, "Tuesday"=>4, "Thursday"=>5} 
      

      正如其他人所指出的,最直接的答案是使用方法Hash::[] 或(在v2.0 中引入)Array#to_h

      Hash[weekdays]
        #=> {"Monday"=>2, "Tuesday"=>4, "Thursday"=>5}
      
      Hash[*weekdays.flatten] #=> Hash["Monday", 2, "Tuesday", 4, "Thursday", 5] 
        #=> {"Monday"=>2, "Tuesday"=>4, "Thursday"=>5}
      
      weekdays.to_h
        #=> {"Monday"=>2, "Tuesday"=>4, "Thursday"=>5}
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2021-01-17
        • 1970-01-01
        • 1970-01-01
        • 2010-12-11
        • 2021-10-16
        • 1970-01-01
        • 2021-11-25
        • 1970-01-01
        相关资源
        最近更新 更多