Arrays 在ruby中将数组转换为哈希
假设我有一个数组Arrays 在ruby中将数组转换为哈希,arrays,json,ruby,hash,Arrays,Json,Ruby,Hash,假设我有一个数组 testarr = [["Actor", "Morgan", "33", ["A","B"]], ["Movie", "Titanic", "44", ["A","A"]], ["Actor", "Jack Black", "333", ["A","A"]]] 我想把它转换成一个散列,最终会转换成json 我想让它看起来像 { "Actor" => { { "name" : "Morgan",
testarr = [["Actor", "Morgan", "33", ["A","B"]],
["Movie", "Titanic", "44", ["A","A"]],
["Actor", "Jack Black", "333", ["A","A"]]]
我想把它转换成一个散列,最终会转换成json
我想让它看起来像
{
"Actor" => {
{ "name" : "Morgan",
"Age" : 33",
"Films: { "A", "B" }} ,
{ "name" : "Jack Black",
"Age" : 44",
"Films: { "A", "A" }}
}
"Movie" => {
{ "Title" : "Titanic"
"Gross" : "44"
"Actors" : { "A", "A" }
}
}
不确定确切的格式,但不管什么都有意义
我试过了
def hashing(arr)
hash = Hash.new
arr.each do |item|
if item[0] == "Movie"
item.delete("Movie")
hash["Movie"] = item
item["Title"] = item[1]
item["Movie"]["Box Office"] = item[2]
item["Movie"]["Actors"] = item[3]
else
item.delete("Actor")
hash["Actor"] = item
item["Actor"]["Name"] == item[1]
item["Actor"]["Age"] == item[2]
item["Actor"]["Filmography"] == item[3]
end
end
return hash
end
testarr = [["Actor", "Morgan", "33", ["dsfds","dsfdsf"]],
["Movie", "Titanic", "44", ["dsfds","dfdsf"]],
["Actor", "Jack Black", "333", ["ssdsfds","dsfdsf"]]]
puts hashing(testarr)
但它给了我一个错误,将数组项放入“Movie”和“Actor”,然后尝试创建“Name”和“Age”等键
我怎样才能按照我的要求来做呢?请尝试下面的代码
v = [["Actor", "Morgan", "33", ["A", "B"]], ["Movie", "Titanic", "44", ["A", "A"]], ["Actor", "Jack Black", "333", ["A", "A"]]]
v.inject({}) do |ot, arr|
item = {name: arr[1], age: arr[2], films: arr[3]}
if ot[arr[0]].present?
ot[arr[0]] << item
else
ot[arr[0]] = []
ot[arr[0]] << item
end
ot
end
请注意这里的Actor不是散列,而是散列数组,这是保存集合的标准方法,如果需要,可以使用to_json方法将其转换为json。请尝试下面的代码
v = [["Actor", "Morgan", "33", ["A", "B"]], ["Movie", "Titanic", "44", ["A", "A"]], ["Actor", "Jack Black", "333", ["A", "A"]]]
v.inject({}) do |ot, arr|
item = {name: arr[1], age: arr[2], films: arr[3]}
if ot[arr[0]].present?
ot[arr[0]] << item
else
ot[arr[0]] = []
ot[arr[0]] << item
end
ot
end
testarr = [["Actor", "Morgan", "33", ["A","B"]],
["Movie", "Titanic", "44", ["A","A"]],
["Actor", "Jack Black", "333", ["A","A"]]]
a = Hash.new{ |h,k| h[k] = [] }
testarr.each do |arr|
b = {name: arr[1], age: arr[2], films: arr[3]}
a[arr[0]] << b
end
请注意这里的Actor不是散列,而是散列数组,这是保存集合的标准方法,如果需要,可以使用to_json方法将其转换为json。您需要迭代数组并解析每个项,将其附加到结果散列中
testarr = [["Actor", "Morgan", "33", ["A","B"]],
["Movie", "Titanic", "44", ["A","A"]],
["Actor", "Jack Black", "333", ["A","A"]]]
a = Hash.new{ |h,k| h[k] = [] }
testarr.each do |arr|
b = {name: arr[1], age: arr[2], films: arr[3]}
a[arr[0]] << b
end
testarr = [["Actor", "Morgan", "33", ["A", "B"]],
["Movie", "Titanic", "44", ["A", "A"]],
["Actor", "Jack Black", "333", ["A", "A"]]]
results = {}
testarr.each do |item|
key, a, b, c = item
r = if key == 'Actor'
{ name: a, age: b, movies: c }
elsif key == 'Movie'
{ title: a, gross: b, actors: c }
end
results[key] = [] unless results[key]
results[key] << r
end
puts results
您需要遍历数组并解析每个项,将其附加到结果哈希中
testarr = [["Actor", "Morgan", "33", ["A", "B"]],
["Movie", "Titanic", "44", ["A", "A"]],
["Actor", "Jack Black", "333", ["A", "A"]]]
results = {}
testarr.each do |item|
key, a, b, c = item
r = if key == 'Actor'
{ name: a, age: b, movies: c }
elsif key == 'Movie'
{ title: a, gross: b, actors: c }
end
results[key] = [] unless results[key]
results[key] << r
end
puts results
:actor
中的值包含一个没有键的散列。你能做的最好的事情就是把它放到一个数组中
这会奏效的。可能有更干净的方法,但我不确定目前如何:
h=Hash.new{| Hash,key | Hash[key]=[]}
testarr=[“演员”、“摩根”、“33”、“A”、“B”]、[“电影”、“泰坦尼克号”、“44”、“A”、“A”]、[“演员”、“杰克·布莱克”、“333”、“A”、“A”]]
每一个都有|
如果t[0]=“电影”
h[t[0]]“摩根”,“年龄=>”33“,:电影=>[“A”,“B”]},{:姓名=>“杰克·布莱克”,“年龄=>”333“,:电影=>[“A”,“A”]}],“电影=>[{:标题=>“泰坦尼克号”,“格罗斯=>”44“,:演员=>[“A”,“A”]}]
您的:actor
中的值包含一个没有键的散列。你能做的最好的事情就是把它放到一个数组中
这会奏效的。可能有更干净的方法,但我不确定目前如何:
h=Hash.new{| Hash,key | Hash[key]=[]}
testarr=[“演员”、“摩根”、“33”、“A”、“B”]、[“电影”、“泰坦尼克号”、“44”、“A”、“A”]、[“演员”、“杰克·布莱克”、“333”、“A”、“A”]]
每一个都有|
如果t[0]=“电影”
h[t[0]]“摩根”,“年龄=>”33“,:电影=>[“A”,“B”]},{:姓名=>“杰克·布莱克”,“年龄=>”333“,:电影=>[“A”,“A”]}],“电影=>[{:标题=>“泰坦尼克号”,“格罗斯=>”44“,:演员=>[“A”,“A”]}]
我试图保留您编写的示例
首先,它必须是为数组(例如[a,b]
)而不是散列({a,b}
)项列表成形的
# You may want result like this ...
{
"Actor": [ # not '{' but '['
{
"name": "Morgan",
"Age": "33",
"Films": ["A", "B"] # not '{' but '[' also
},
{
"name": "Jack Black",
"Age": "44",
"Films": ["A", "A"]
}
],
"Movie": [
{
"Title": "Titanic",
"Gross": "44",
"Actors": ["A", "A"]
}
]
}
然后你的函数应该是这样的
def hashing(arr)
hash = Hash.new
hash["Movie"], hash["Actor"] = [], []
arr.each do |item|
if item[0] == "Movie"
movie = {}
movie["Title"] = item[1]
movie["Box Office"] = item[2]
movie["Actors"] = item[3]
item.delete("Movie") # optional
hash["Movie"] << movie
else
actor = {}
actor["Name"] = item[1]
actor["Age"] = item[2]
actor["Filmography"] = item[3]
item.delete("Actor") # optional
hash["Actor"] << actor
end
end
return hash
end
它将返回以下内容:
{
"Movie"=>
[
{"Title"=>"Titanic", "Box Office"=>"44", "Actors"=>["dsfds", "dfdsf"]}
],
"Actor"=>
[
{"Name"=>"Morgan", "Age"=>"33", "Filmography"=>["dsfds", "dsfdsf"]},
{"Name"=>"Jack Black", "Age"=>"333", "Filmography"=>["ssdsfds", "dsfdsf"]}
]
}
我试着保留你写的例子 首先,它必须是为数组(例如
[a,b]
)而不是散列({a,b}
)项列表成形的
# You may want result like this ...
{
"Actor": [ # not '{' but '['
{
"name": "Morgan",
"Age": "33",
"Films": ["A", "B"] # not '{' but '[' also
},
{
"name": "Jack Black",
"Age": "44",
"Films": ["A", "A"]
}
],
"Movie": [
{
"Title": "Titanic",
"Gross": "44",
"Actors": ["A", "A"]
}
]
}
然后你的函数应该是这样的
def hashing(arr)
hash = Hash.new
hash["Movie"], hash["Actor"] = [], []
arr.each do |item|
if item[0] == "Movie"
movie = {}
movie["Title"] = item[1]
movie["Box Office"] = item[2]
movie["Actors"] = item[3]
item.delete("Movie") # optional
hash["Movie"] << movie
else
actor = {}
actor["Name"] = item[1]
actor["Age"] = item[2]
actor["Filmography"] = item[3]
item.delete("Actor") # optional
hash["Actor"] << actor
end
end
return hash
end
它将返回以下内容:
{
"Movie"=>
[
{"Title"=>"Titanic", "Box Office"=>"44", "Actors"=>["dsfds", "dfdsf"]}
],
"Actor"=>
[
{"Name"=>"Morgan", "Age"=>"33", "Filmography"=>["dsfds", "dsfdsf"]},
{"Name"=>"Jack Black", "Age"=>"333", "Filmography"=>["ssdsfds", "dsfdsf"]}
]
}
代码
def convert(arr, keys)
arr.group_by(&:first).transform_values do |a|
a.map { |key, *values| keys[key].zip(values).to_h }
end
end
示例(使用问题中定义的testarr
)
解释
keys = { "Actor"=>[:name, :Age, :Films], "Movie"=>[:Title, :Gross, :Actors] }
convert(testarr, keys)
#=> { "Actor"=>[
# {:name=>"Morgan", :Age=>"33", :Films=>["A", "B"]},
# {:name=>"Jack Black", :Age=>"333", :Films=>["A", "A"]}
# ],
# "Movie"=>[
# {:Title=>"Titanic", :Gross=>"44", :Actors=>["A", "A"]}
# ]
# }
看,还有
步骤如下
h = testarr.group_by(&:first)
#=> { "Actor"=>[
# ["Actor", "Morgan", "33", ["A", "B"]],
# ["Actor", "Jack Black", "333", ["A", "A"]]
# ],
# "Movie"=>[
# ["Movie", "Titanic", "44", ["A", "A"]]
# ]
# }
虽然不完全相同,但您可以将testarr.group_by(&:first)
看作是{a | a.first}的testarr.group_的“速记”。继续
e0 = h.transform_values
#=> #<Enumerator:
# {"Actor"=>[["Actor", "Morgan", "33", ["A", "B"]],
# ["Actor", "Jack Black", "333", ["A", "A"]]],
# "Movie"=>[["Movie", "Titanic", "44", ["A", "A"]]]}
# :transform_values>
现在创建了第二个枚举数
e1 = a.map
#=> #<Enumerator: [["Actor", "Morgan", "33", ["A", "B"]],
# ["Actor", "Jack Black", "333", ["A", "A"]]]:map>
现在将执行内部块计算
b = keys[key].zip(values)
#=> keys["Actor"].zip(["Morgan", "33", ["A", "B"]])
#=> [:name, :Age, :Films].zip(["Morgan", "33", ["A", "B"]])
#=> [[:name, "Morgan"], [:Age, "33"], [:Films, ["A", "B"]]]
b.to_h
#=> {:name=>"Morgan", :Age=>"33", :Films=>["A", "B"]}
key, *values = e1.next
#=> ["Actor", "Jack Black", "333", ["A", "A"]]
b = keys[key].zip(values)
#=> [[:name, "Jack Black"], [:Age, "333"], [:Films, ["A", "A"]]]
b.to_h
#=> {:name=>"Jack Black", :Age=>"333", :Films=>["A", "A"]}
现在,第二个也是最后一个元素由e1
生成,并执行相同的计算
b = keys[key].zip(values)
#=> keys["Actor"].zip(["Morgan", "33", ["A", "B"]])
#=> [:name, :Age, :Films].zip(["Morgan", "33", ["A", "B"]])
#=> [[:name, "Morgan"], [:Age, "33"], [:Films, ["A", "B"]]]
b.to_h
#=> {:name=>"Morgan", :Age=>"33", :Films=>["A", "B"]}
key, *values = e1.next
#=> ["Actor", "Jack Black", "333", ["A", "A"]]
b = keys[key].zip(values)
#=> [[:name, "Jack Black"], [:Age, "333"], [:Films, ["A", "A"]]]
b.to_h
#=> {:name=>"Jack Black", :Age=>"333", :Films=>["A", "A"]}
当从e1
中寻找另一个值时,我们得到以下结果
e1.next
#=> StopIteration: iteration reached an end
捕获此异常,导致e1
返回到外部块。此时e0
生成下一个(和最后一个值)
其余的计算结果类似。代码
def convert(arr, keys)
arr.group_by(&:first).transform_values do |a|
a.map { |key, *values| keys[key].zip(values).to_h }
end
end
示例(使用问题中定义的testarr
)
解释
keys = { "Actor"=>[:name, :Age, :Films], "Movie"=>[:Title, :Gross, :Actors] }
convert(testarr, keys)
#=> { "Actor"=>[
# {:name=>"Morgan", :Age=>"33", :Films=>["A", "B"]},
# {:name=>"Jack Black", :Age=>"333", :Films=>["A", "A"]}
# ],
# "Movie"=>[
# {:Title=>"Titanic", :Gross=>"44", :Actors=>["A", "A"]}
# ]
# }
看,还有
步骤如下
h = testarr.group_by(&:first)
#=> { "Actor"=>[
# ["Actor", "Morgan", "33", ["A", "B"]],
# ["Actor", "Jack Black", "333", ["A", "A"]]
# ],
# "Movie"=>[
# ["Movie", "Titanic", "44", ["A", "A"]]
# ]
# }
虽然不完全相同,但您可以将testarr.group_by(&:first)
看作是{a | a.first}
的testarr.group_的“速记”。继续
e0 = h.transform_values
#=> #<Enumerator:
# {"Actor"=>[["Actor", "Morgan", "33", ["A", "B"]],
# ["Actor", "Jack Black", "333", ["A", "A"]]],
# "Movie"=>[["Movie", "Titanic", "44", ["A", "A"]]]}
# :transform_values>
现在创建了第二个枚举数
e1 = a.map
#=> #<Enumerator: [["Actor", "Morgan", "33", ["A", "B"]],
# ["Actor", "Jack Black", "333", ["A", "A"]]]:map>
现在将执行内部块计算
b = keys[key].zip(values)
#=> keys["Actor"].zip(["Morgan", "33", ["A", "B"]])
#=> [:name, :Age, :Films].zip(["Morgan", "33", ["A", "B"]])
#=> [[:name, "Morgan"], [:Age, "33"], [:Films, ["A", "B"]]]
b.to_h
#=> {:name=>"Morgan", :Age=>"33", :Films=>["A", "B"]}
key, *values = e1.next
#=> ["Actor", "Jack Black", "333", ["A", "A"]]
b = keys[key].zip(values)
#=> [[:name, "Jack Black"], [:Age, "333"], [:Films, ["A", "A"]]]
b.to_h
#=> {:name=>"Jack Black", :Age=>"333", :Films=>["A", "A"]}
现在,第二个也是最后一个元素由e1
生成,并执行相同的计算
b = keys[key].zip(values)
#=> keys["Actor"].zip(["Morgan", "33", ["A", "B"]])
#=> [:name, :Age, :Films].zip(["Morgan", "33", ["A", "B"]])
#=> [[:name, "Morgan"], [:Age, "33"], [:Films, ["A", "B"]]]
b.to_h
#=> {:name=>"Morgan", :Age=>"33", :Films=>["A", "B"]}
key, *values = e1.next
#=> ["Actor", "Jack Black", "333", ["A", "A"]]
b = keys[key].zip(values)
#=> [[:name, "Jack Black"], [:Age, "333"], [:Films, ["A", "A"]]]
b.to_h
#=> {:name=>"Jack Black", :Age=>"333", :Films=>["A", "A"]}
当从e1
中寻找另一个值时,我们得到以下结果
e1.next
#=> StopIteration: iteration reached an end
捕获此异常,导致e1
返回到外部块。此时e0
生成下一个(和最后一个值)
其余的计算结果与此类似。谢谢!但是我为nil:NilClass(nomethoderor)得到了一个未定义的方法'present'。这是一个有效的方法吗?是的,它;s rails标准方法。你到底用不用Rails?我用的是普通的Rubythank!但是我为nil:NilClass(nomethoderor)得到了一个未定义的方法'present'。这是一个有效的方法吗?是的,它;s rails标准方法。你到底用不用Rails?我用的是普通的Rubythank。我怎样才能真正把演员的年龄和从影记录放在名字键里面呢?喜欢名字=>Morgan=>{Age:33,Filmo=[…]}简单!再次包装您的结构。在您的表达式中,Name=>Morgan=>{…}
与包装类似Name=>{Morgan=>{…}
。结构中的所有键都必须具有完整的结构下的值,如我包装的值。顺便说一句,为了更清楚地保护和定义对象,我建议使用原始版本而不是新版本。谢谢。我怎样才能真正把演员的年龄和从影记录放在名字键里面呢?喜欢名字=>Morgan=>{Age:33,Filmo=[…]}简单!再次包装您的结构。在您的表达式中,Name=>Morgan=>{…}
与包装类似Name=>{Morgan=>{…}
。结构中的所有键都必须具有完整的结构下的值,如我包装的值。顺便说一句,我建议protec使用原始版本而不是新版本