使用以下结构将数组转换为ruby中的散列

时间:2023-01-24 21:43:28

I have a following array which displays information of users and some values related to the user. Following array contains information of two users Akiyo Riggs and Bingo

我有一个显示用户信息和与用户相关的一些值的数组。下面的数组包含两个用户Akiyo Riggs和Bingo的信息

a1 = [["Akiyo Riggs", -32, "OverTime Hours", "",12],["Akiyo Riggs", -32, 
"Regular Hours", "", 18],["Bingo",-12,"OverTime Hours","",14], ["Bingo",
-12,"Regular Hours","",32]]

How can i convert into following array of hashes in which key is the user name and value is a hash with respective values

如何转换为以下的散列数组,其中的键是用户名,值是具有各自值的散列

[{"Akiyo Riggs"=>{"OverTime Hours"=>["", 12], "Regular Hours"=>["", 18]},
{"Bingo"=>{"OverTime Hours"=>["", 14], "Regular Hours"=>["", 32]}]

4 个解决方案

#1


4  

a1.map { |x,_,p,*ps| {x => {p => ps} } }.reduce({}, :deep_merge)
# => {"Akiyo Riggs"=>{"OverTime Hours"=>["", 12], "Regular Hours"=>["", 18]},
#     "Bingo"=>{"OverTime Hours"=>["", 14], "Regular Hours"=>["", 32]}}

Note: if efficiency is concerned, consider using deep_merge! instead of deep_merge, so that reduce wouldn't create a new hash on every iteration.

注意:如果考虑到效率,请考虑使用deep_merge!而不是deep_merge,这样reduce就不会在每次迭代中创建新的散列。

Some explanation:

这里做一些解释:

a1.map { |x,_,p,*ps| {x => {p => ps} } }

gives us an array of hashes like this

给我们一个像这样的哈希数组

 [{"Akiyo Riggs"=>{"OverTime Hours"=>["", 12]}},
  {"Akiyo Riggs"=>{"Regular Hours"=>["", 18]}},
  {"Bingo"=>{"OverTime Hours"=>["", 14]}},
  {"Bingo"=>{"Regular Hours"=>["", 32]}}]

which we can recursively merge with ActiveSupport Hash#deep_merge

我们可以用ActiveSupport散列#deep_merge进行递归合并

#2


2  

You can do something like this (however, this is not quite that is you want exactly):

你可以做这样的事情(然而,这并不是你想要的那样):

res = a1.group_by {|x| x[0] }.reduce({}) {|h, x| h[ x[0] ] = x[1].reduce({}) {|hh, xx| hh[ xx[2] ] = xx[3..-1] ; hh } ; h }
# => {"Akiyo Riggs"=>{"OverTime Hours"=>["", 12], "Regular Hours"=>["", 18]}, "Bingo"=>{"OverTime Hours"=>["", 14], "Regular Hours"=>["", 32]}}

the exact thing is doing with additional step:

具体的做法是采取额外的步骤:

res.keys.map {|k| {k => res[k]}}
# => [{"Akiyo Riggs"=>{"OverTime Hours"=>["", 12], "Regular Hours"=>["", 18]}}, {"Bingo"=>{"OverTime Hours"=>["", 14], "Regular Hours"=>["", 32]}}]

#3


1  

a1.each_with_object({}) do |array, result|
  result[array[0]] ||= {}
  result[array[0]].merge!(array[2] => [array[3], array[4]])
end.map { |k, v| { k => v } }

# => [{"Akiyo Riggs"=>{"OverTime Hours"=>["", 12], "Regular Hours"=>["", 18]}}, {"Bingo"=>{"OverTime Hours"=>["", 14], "Regular Hours"=>["", 32]}}] 

#4


1  

array.each_with_object({}) do |(name, _, hours_type, a, b), hash|
  hash[name] ||= {}
  hash[name][hours_type] = [a, b]
end.map do |name, values_hash|
  {name => values_hash}
end

#1


4  

a1.map { |x,_,p,*ps| {x => {p => ps} } }.reduce({}, :deep_merge)
# => {"Akiyo Riggs"=>{"OverTime Hours"=>["", 12], "Regular Hours"=>["", 18]},
#     "Bingo"=>{"OverTime Hours"=>["", 14], "Regular Hours"=>["", 32]}}

Note: if efficiency is concerned, consider using deep_merge! instead of deep_merge, so that reduce wouldn't create a new hash on every iteration.

注意:如果考虑到效率,请考虑使用deep_merge!而不是deep_merge,这样reduce就不会在每次迭代中创建新的散列。

Some explanation:

这里做一些解释:

a1.map { |x,_,p,*ps| {x => {p => ps} } }

gives us an array of hashes like this

给我们一个像这样的哈希数组

 [{"Akiyo Riggs"=>{"OverTime Hours"=>["", 12]}},
  {"Akiyo Riggs"=>{"Regular Hours"=>["", 18]}},
  {"Bingo"=>{"OverTime Hours"=>["", 14]}},
  {"Bingo"=>{"Regular Hours"=>["", 32]}}]

which we can recursively merge with ActiveSupport Hash#deep_merge

我们可以用ActiveSupport散列#deep_merge进行递归合并

#2


2  

You can do something like this (however, this is not quite that is you want exactly):

你可以做这样的事情(然而,这并不是你想要的那样):

res = a1.group_by {|x| x[0] }.reduce({}) {|h, x| h[ x[0] ] = x[1].reduce({}) {|hh, xx| hh[ xx[2] ] = xx[3..-1] ; hh } ; h }
# => {"Akiyo Riggs"=>{"OverTime Hours"=>["", 12], "Regular Hours"=>["", 18]}, "Bingo"=>{"OverTime Hours"=>["", 14], "Regular Hours"=>["", 32]}}

the exact thing is doing with additional step:

具体的做法是采取额外的步骤:

res.keys.map {|k| {k => res[k]}}
# => [{"Akiyo Riggs"=>{"OverTime Hours"=>["", 12], "Regular Hours"=>["", 18]}}, {"Bingo"=>{"OverTime Hours"=>["", 14], "Regular Hours"=>["", 32]}}]

#3


1  

a1.each_with_object({}) do |array, result|
  result[array[0]] ||= {}
  result[array[0]].merge!(array[2] => [array[3], array[4]])
end.map { |k, v| { k => v } }

# => [{"Akiyo Riggs"=>{"OverTime Hours"=>["", 12], "Regular Hours"=>["", 18]}}, {"Bingo"=>{"OverTime Hours"=>["", 14], "Regular Hours"=>["", 32]}}] 

#4


1  

array.each_with_object({}) do |(name, _, hours_type, a, b), hash|
  hash[name] ||= {}
  hash[name][hours_type] = [a, b]
end.map do |name, values_hash|
  {name => values_hash}
end