2017-08-07 57 views
-2

我尝试写一些代码来此嵌套数组的元素转换:Coverting嵌套数组中某些元素的哈希

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, ...} 

如果任何人有一个简单的方法来理解代码,这将是感恩。

+0

他们总是只是号码,名称,中心和点? –

+0

他们是 - 号码,名字,位置,点数。 – Dave

+0

该数组来自哪里? – Stefan

回答

2

它更有意义使用数组users(而不是变量user1,user2等),因此代码将与任意数量的用户一起使用。用户i的值为user[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"} 

其余的计算是类似的。

+1

好主意来使用'product'。链中的最后一个链接可以是.map {| a | a.transpose.to_h}'如果你愿意的话。 –

+0

感谢您的建议@ sagarpandya82。我会做出改变。 –

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

请注意,计算出的散列中的键将是符号。你可以插入'header.map!(&:to_sym)'语句' –

1

你可以得到拍摄第一阵列主阵列中喜欢下散列每个键:

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个值中的每个阵列中每个人的哈希值,并使用在每个值键阵列像散列键:

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"} 
# ] 

有了这个你可以迭代它,或者根据需要创建你的本地或实例变量。

2

为了让您的数据与字段和用户任意数量的输出例如,你可能做这样的事情:

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"}}