【问题标题】:can't figure out array of hashes ruby无法计算出哈希红宝石数组
【发布时间】:2017-06-15 04:56:33
【问题描述】:

我正在尝试将数组数组转换为哈希数组。有人可以尝试解释我在这里到底做错了什么吗?数组数组中的第一个数组成为散列的键。我可以获得返回一个哈希甚至三个相同哈希的方法。但我无法让它在最终数组中返回每个不同的新哈希。

table_data = [
  ["first_name", "last_name", "city", "state"],
  ["Elisabeth", "Gardenar", "Toledo", "OH"],
  ["Jamaal", "Du", "Sylvania", "OH"],
  ["Kathlyn", "Lavoie", "Maumee", "OH"]
]


def convert_table(table_array)
  hash = {}
  final_array = []
  headers_array = table_array.shift

  table_array.each_index do |x|
    i = 0
    until i == headers_array.length
      hash[headers_array[i]] = table_array[x][i]
      final_array << hash
      i += 1
    end
  end
  final_array
end

p convert_table(table_data)

#END GOAL
[ { "first_name" => "Elisabeth", "last_name" => "Gardenar", "city" => "Toledo", "state" => "OH" },
{ "first_name" => "Jamaal", "last_name" => "Du", "city" => "Sylvania", "state"    => "OH" },
{ "first_name" => "Kathlyn", "last_name" => "Lavoie", "city" => "Maumee", "state" => "OH" }

【问题讨论】:

  • 如果您确实会说英语,请阅读以下评论,您成功地永远忽略了它:我注意到您从不接受针对您的问题给出的答案。确保花一些时间检查您的问题并接受他们解决您问题的最佳答案。通过这种方式,您可以让社区知道问题已解决,同时您奖励提供解决方案的人的努力。要接受答案,请查看答案分数下的复选标记。
  • 未提供 MCVE,未说明任何问题。投反对票。
  • 我说英语。我不熟悉这个网站的运作方式。现在我很熟悉,并且正在检查我的问题并选择正确的答案。我看到了这样做的价值和必要性。无需尝试和侮辱。如果您想对语法挑剔,我会改写“永远成功地忽略”。 “成功”是现在时。这是你可以携带你的陈述的最远距离。 “永远”是行不通的。下次你问是否有人会说英语时,请忽略那部分。在问这个问题时,使用非常清晰的英语非常重要......永远(呵呵)

标签: arrays ruby hash nested


【解决方案1】:

使用zip 将键(table_data[0] 中的键和值(table_data 中的另一行)配对,并将它们映射到哈希:

table_data[1..-1].map { |values| Hash[table_data[0].zip(values)] }

编辑:在您的情况下不起作用的部分是拥有一个您不断重复使用的哈希。当您执行final_array &lt;&lt; hash 时,它不会像当时那样添加哈希快照;它添加了一个 reference 给它。因此,您没有一个包含三个哈希的数组,而是一个包含三个对同一哈希的引用的数组。您可以通过 final_array &lt;&lt; hash.clone 实际拍摄快照来避免它;或者(更简单)只是在循环的每次迭代中创建一个新的哈希(将hash = {} 移动到table_array.each_index 循环中)。

【讨论】:

  • 谢谢。但是你能告诉我我的逻辑有什么问题吗?我认为我的 until 循环会创建每个正确的单个散列......确实如此。然后直到结束。但是 each_index 没有完成并且在 until 循环中保持不变。然后循环应该使 x(索引)= 1,并且应该创建第二个人的新哈希。我的哈希每次都会被覆盖吗?
  • 已编辑。下次还请说明你的代码有什么问题,不要让我们运行或分析它只是为了找出你的问题。
【解决方案2】:

@Amadan 已诊断出您的问题,我将建议一种更“类似于 Ruby”的方法。

keys, *data = table_data
  #=> [["first_name", "last_name", "city", "state"],
  #    ["Elisabeth", "Gardenar", "Toledo", "OH"],
  #    ["Jamaal", "Du", "Sylvania", "OH"],
  #    ["Kathlyn", "Lavoie", "Maumee", "OH"]
  #   ]
keys
  #=> ["first_name", "last_name", "city", "state"] 
data
  #=> [["Elisabeth", "Gardenar", "Toledo", "OH"],
  #    ["Jamaal", "Du", "Sylvania", "OH"],
  #    ["Kathlyn", "Lavoie", "Maumee", "OH"]
  #   ] 

[keys].product(data).map { |pair| pair.transpose.to_h }
  #=> [{"first_name"=>"Elisabeth", "last_name"=>"Gardenar", "city"=>"Toledo", 
  #       "state"=>"OH"},
  #    {"first_name"=>"Jamaal", "last_name"=>"Du", "city"=>"Sylvania",
  #       "state"=>"OH"},
  #    {"first_name"=>"Kathlyn", "last_name"=>"Lavoie", "city"=>"Maumee",
  #       "state"=>"OH"}
  #   ] 

步骤如下。

a = [keys].product(data)
  #=> [[["first_name", "last_name", "city", "state"],
  #     ["Elisabeth", "Gardenar", "Toledo", "OH"]
  #    ],
  #    [["first_name", "last_name", "city", "state"],
  #     ["Jamaal", "Du", "Sylvania", "OH"]],
  #    [["first_name", "last_name", "city", "state"],
  #     ["Kathlyn", "Lavoie", "Maumee", "OH"]
  #    ]
  #   ] 

a的第一个元素传递给map,赋值块变量pair并进行块计算。

pair = a.first
  #=> [["first_name", "last_name", "city", "state"],
  #    ["Elisabeth", "Gardenar", "Toledo", "OH"]
  #   ] 
b = pair.transpose
  #=> [["first_name", "Elisabeth"],
  #    ["last_name", "Gardenar"],
  #    ["city", "Toledo"],
  #    ["state", "OH"]
  #   ] 
g = b.to_h
  #=> {"first_name"=>"Elisabeth", "last_name"=>"Gardenar", "city"=>"Toledo",
  #      "state"=>"OH"} 

因此,a.first 映射到 g。其余计算类似。

【讨论】:

    【解决方案3】:

    @CarySwoveland 和 @Amadan 已正确回答您的问题。

    我想补充一点,您的表格基本上看起来像带有标题的 CSV 表格。

    如果你的table_data确实来自一个文件,你不妨直接用CSV阅读它:

    csv_table = "first_name,last_name,city,state
    Elisabeth,Gardenar,Toledo,OH
    Jamaal,Du,Sylvania,OH
    Kathlyn,Lavoie,Maumee,OH"
    
    require 'csv'
    
    CSV.parse(csv_table, headers: true).each do |row|
      p row
    end
    

    输出

    #<CSV::Row "first_name":"Elisabeth" "last_name":"Gardenar" "city":"Toledo" "state":"OH">
    #<CSV::Row "first_name":"Jamaal" "last_name":"Du" "city":"Sylvania" "state":"OH">
    #<CSV::Row "first_name":"Kathlyn" "last_name":"Lavoie" "city":"Maumee" "state":"OH">
    

    您可以像处理哈希一样使用CSV::Row。 如果你真的想要一个哈希,你可以使用row.to_h

    {"first_name"=>"Elisabeth", "last_name"=>"Gardenar", "city"=>"Toledo", "state"=>"OH"}
    {"first_name"=>"Jamaal", "last_name"=>"Du", "city"=>"Sylvania", "state"=>"OH"}
    {"first_name"=>"Kathlyn", "last_name"=>"Lavoie", "city"=>"Maumee", "state"=>"OH"}
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2019-04-23
      • 1970-01-01
      • 2012-12-19
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-12-24
      • 1970-01-01
      相关资源
      最近更新 更多