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使用原始版本而不是新版本