Ruby - 将嵌套哈希转换为多维数组

时间:2017-09-01 15:00:33

标签: arrays ruby list dictionary hash

我有一个名为h的哈希。我想将内容存储在名为ar的多维数组中。我收到错误no implicit conversion from nil to integer

这是我的代码:

h = {"bob" => {email: "abc" , tel: "123"} , "daisy" => {email: "cab" , tel: "123456"}}

keys = h.keys

l = h.length 

ar = Array.new(l) { Array.new(3) }

for i in 0..l-1
  ar[[2][i]] = keys[i]
  ar[[1][i]] = h[keys[i]][:email]
  ar[[0][i]] = h[keys[i]][:tel]
end

puts ar.to_s

所需的输出是:

[[email_1, email_2, ..][tel_1, tel_2, ..][name_1, name_2, ..]]

例如:

[["abc", "cab"] , ["123", "123456"] , ["bob", "daisy"]]

4 个答案:

答案 0 :(得分:2)

[2][i]会为nil返回i > 0ar[nil]提出异常。

以下是您的工作:

arr = h.map { |k, v| [v[:email], v[:tel], k] }.reduce(&:zip)

使 代码正常工作:

更改

ar = Array.new(l) { Array.new(3) }

ar = Array.new(3) { Array.new(l) }

更改

ar[[2][i]] = keys[i]
ar[[1][i]] = h[keys[i]][:email]
ar[[0][i]] = h[keys[i]][:tel]

ar[2][i] = keys[i]
ar[1][i] = h[keys[i]][:email]
ar[0][i] = h[keys[i]][:tel]

答案 1 :(得分:2)

这是我处理这个问题的方式:

h.values.each_with_object({}) do |h,obj|
  obj.merge!(h) { |_k,v1,v2| ([v1] << v2).flatten }
end.values << h.keys
#=> [["abc", "cab"], ["123", "123456"], ["bob", "daisy"]]
  • 首先抓住所有values(作为哈希)
  • 使用累加器({}
  • 循环遍历它们
  • merge!累加器和冲突中的值会将它们附加到array
  • 从累加器
  • 返回values
  • 然后附加原始keys

这比@ mudasobwa的答案更不明确,并且依赖于第一个value的顺序来确定输出。例如if:tel之前:电子邮件前2个元素将有相反的顺序

答案 2 :(得分:1)

您最常应该做的是停止使用Ruby语法编写PHP代码。这是如何在Ruby中完成的:

h.map { |k, v| [v[:email], v[:tel], k] }.reduce(&:zip)

或者更好的是,如果您确定嵌套哈希中的元素顺序:

h.map { |k, v| [*v.values, k] }.reduce(&:zip).map(&:flatten)

所有方法mapreducezip都在the documentation中详细说明。

答案 3 :(得分:0)

h.map { |k, v| [*v.values_at(:email, :tel), k] }.transpose
  #=> [["abc", "cab"], ["123", "123456"], ["bob", "daisy"]]

中间计算如下。

h.map { |k, v| [*v.values_at(:email, :tel), k] }
  #=> [["abc", "123", "bob"], ["cab", "123456", "daisy"]]