将嵌套数组中的某些元素覆盖到哈希中



我正在尝试编写一些代码来转换此嵌套数组的元素:

array = [
[['number'], ['name'], ['postion'], ['points']],
[['91'], ['dave'], ['center'], ['42']],
[['82'], ['sanjay'], ['behind'], ['14']],
[['133'], ['ayman'], ['front'], ['23']]
]

到这样的哈希

user1 = {number: 91, name: dave, postion: center, points: 42}
user2 = {number: 82, name: Sanjay, ...}

如果有人有一个简单的方法来理解代码,那将不胜感激。

header, *data = array.map(&:flatten)
user1, user2, user3 = data.map { |row| header.zip(row).to_h }

使用数组users(而不是变量user1user2等(更有意义,这样代码就可以处理任意数量的用户。然后user[i]用户i的值(从用户0开始计数(。

keys, *values = array.map(&:flatten)
users = [keys.map(&:to_sym)].product(values).map { |pair| pair.transpose.to_h }
#=> [{:number=>"91", :name=>"dave", :postion=>"center", :points=>"42"},
#    {:number=>"82", :name=>"sanjay", :postion=>"behind", :points=>"14"},
#    {:number=>"133", :name=>"ayman", :postion=>"front", :points=>"23"}]

步骤如下。

keys, *values = array.map(&:flatten)
#=> [["number", "name", "postion", "points"],
#    ["91", "dave", "center", "42"],
#    ["82", "sanjay", "behind", "14"],
#    ["133", "ayman", "front", "23"]]
keys
#=> ["number", "name", "postion", "points"]
values
#=> [["91", "dave", "center", "42"],
#    ["82", "sanjay", "behind", "14"],
#    ["133", "ayman", "front", "23"]]
a = keys.map(&:to_sym)
#=> [:number, :name, :postion, :points]
b = [a]
#=> [[:number, :name, :postion, :points]]
c = b.product(values)
#=> [[[:number, :name, :postion, :points], ["91", "dave", "center", "42"]],
[[:number, :name, :postion, :points], ["82", "sanjay", "behind", "14"]],
[[:number, :name, :postion, :points], ["133", "ayman", "front", "23"]]]
c.map { |pair| pair.transpose.to_h }
# <return value above>

当执行最后一步时,c的每个元素都传递给块,块变量pair被分配给该值并执行块计算。当c的第一个元素传递给块时,将执行以下步骤。

pair = c.first
#=> [[:number, :name, :postion, :points], ["91", "dave", "center", "42"]]
d = pair.transpose
#=> [[:number, "91"], [:name, "dave"], [:postion, "center"], [:points, "42"]]
d.to_h
#=> {:number=>"91", :name=>"dave", :postion=>"center", :points=>"42"}

其余计算类似。

若要将数据发送到具有任意数量的字段和用户的示例输出,可以执行以下操作:

array =  [
[['number'], ['name'], ['postion'], ['points']],
[  ['91'],  ['dave'], ['center'],  ['42']],
[  ['82'],   ['sanjay'],  ['behind'],    ['14']],
[  ['133'], ['ayman'], ['front'],    ['23']]]
temp, data={},{}
array.transpose.map { |(h, *rest)| temp[h]=rest.flatten }
(1..temp.max_by { |k,v| v.length }[1].length)
.each_with_index { |n, i| data["user%d" % [n]]=temp.map { |k,l| [k[0], l[i]] } }
data.map { |k, v| data[k]=v.to_h }   

然后你会得到:

> data 
{"user1"=>{"number"=>"91", "name"=>"dave", "postion"=>"center", "points"=>"42"}, "user2"=>{"number"=>"82", "name"=>"sanjay", "postion"=>"behind", "points"=>"14"}, "user3"=>{"number"=>"133", "name"=>"ayman", "postion"=>"front", "points"=>"23"}}

您可以获取下一个哈希的每个键,采用主数组中的第一个数组,如下所示:

array.first.flatten
# => ["number", "name", "postion", "points"]

因此,然后您可以获取数组的其余部分,从索引 1 开始到最后一个元素,"扁平化"它并得到一个每 4 个值的数组,例如:

p array[1..-1].flatten.each_slice(4).to_a
[["91", "dave", "center", "42"], ["82", "sanjay", "behind", "14"], ["133", "ayman", "front", "23"]]

因此,您可以为每个数组创建一个哈希,每个数组中有 4 个值,并使用 keys 数组中的每个值,如哈希键:

p array[1..-1].flatten.each_slice(4).map.with_index{|e,i|
Hash[e.map.with_index{|f,i| [keys[i], f]}]
}
# [
#   {"number"=>"91",  "name"=>"dave",   "postion"=>"center", "points"=>"42"}, 
#   {"number"=>"82",  "name"=>"sanjay", "postion"=>"behind", "points"=>"14"}, 
#   {"number"=>"133", "name"=>"ayman",  "postion"=>"front",  "points"=>"23"}
# ]

有了它,您可以迭代它,或根据需要创建局部或实例变量。

最新更新