2014-11-04 161 views
-1
散列变换阵列

我有以下散列:组和在红宝石

hash = {"col1"=>["FALSE", "TRUE", "FALSE", "TRUE"], 
"col2"=>["FALSE", "FALSE", "TRUE", "TRUE"], 
"Freq"=>[36146, 2614, 2607, 1692]} 

我想以上通过COL1分组它来创建两个散列出一个阵列;第一个散列将包含:name =>“FALSE”,第二个散列将包含:name =>“TRUE”。

目标是获得以下哈希数组。下面第一个哈希中的value1和value2对应于col2中归因于FALSE和TRUE的频率。

[{name=> FALSE, value1 => 36146, value2 => 2607 }, 
{name=> TRUE, value1 => 2614, value2 => 1692 }] 

谢谢!

+0

需要一些修改'name','value1'和'value2'必须转换为字符串(' “名” ')或符号(':name')。必须将“FALSE”和“TRUE”转换为字符串,符号或“false”或“true”对象。看到我的想法答案。 – 2014-11-05 05:20:35

+0

您需要修改以澄清问题。如果我的理解是正确的,例如:“我希望创建一个包含两个哈希的数组,第一个哈希包含':name =>”FALSE“'和另外两个键 - 值对。在hash [“col1”]'值等于“FALSE”(这里偏移了'0'和'2')的值的偏移处设置hash [“col2”]'('hash [“Freq”]')那将是'“FALSE”=> 36146“'和'”TRUE“=> 2607')。除了用于hash [“col1”]'等于'“TRUE”(在偏移量为1和3)的元素外,第二个散列的构造方式类似。“随意使用这些 – 2014-11-05 05:43:36

+0

当我说需要更正和澄清时,我的意思是你需要编辑你的问题,因为目前有三张投票结束,你应该这样做* post haste *。 – 2014-11-05 16:22:25

回答

0

我相信这会产生你想要的散列数组。我改变了一些值的名称,以使结果更易于理解。

hash = {"col1"=>["FALSE", "TRUE", "FALSE", "TRUE"], 
     "col2"=>["FALSE", "FALSE", "TRUE", "TRUE"], 
     "Freq"=>[36146, 2614, 2607, 1692]} 

arr = hash["col1"].zip(hash["col2"], hash["Freq"]) 
    #=> [["FALSE", "FALSE", 36146], ["TRUE", "FALSE", 2614], 
    # ["FALSE", "TRUE", 2607], ["TRUE", "TRUE", 1692]] 

arr.each_with_object({}) do |(tf1,tf2,freq),h| 
    (h[tf1] ||= {})[:name] = tf1+?1 
    h[tf1][tf2+?2] = freq 
end.values 
    #=> [{:name=>"FALSE1", "FALSE2"=>36146, "TRUE2"=>2607}, 
    # {:name=>"TRUE1", "FALSE2"=>2614, "TRUE2"=>1692}] 

Enumerable#zip用于产生阵列arr其值如上所示。

enum = arr.each_with_object({}) 
    #=> #<Enumerator: [["FALSE", "FALSE", 36146], ["TRUE", "FALSE", 2614], 
    # ["FALSE", "TRUE", 2607], ["TRUE", "TRUE", 1692]]:each_with_object({})> 

我们可以枚举转换为阵,看看什么样的价值观也将传递到它的块:

enum.to_a 
    #=> [[["FALSE", "FALSE", 36146], {}], [["TRUE", "FALSE", 2614], {}], 
    # [["FALSE", "TRUE", 2607], {}], [["TRUE", "TRUE", 1692], {}]] 

注意,经过哈希的元素值的第一个(在每个AS {}所示)在元素传递到块时将是非空的。

第一阵列,

[["FALSE", "FALSE", 36146], {}] 

被传递到块,分解并分配给块的变量:

tf1 = "FALSE" 
tf2 = "FALSE" 
freq = 36146 
h = {} 

然后,我们执行以下操作:

(h[tf1] ||= {})[:name] = tf1+?1 
    # (h["FALSE"] ||= {})[:name] = "FALSE"+?1 
    # h["FALSE"] = h["FALSE"] || {})[:name] = "FALSE1" 
    # h["FALSE"] = nil || {})[:name] = "FALSE1" 
    # h["FALSE"] = {})[:name] = "FALSE1" 
    # h => {"FALSE"=>{:name=>"FALSE1"}} 

h[tf1][tf2+?2] = freq 
    # h["FALSE"]["FALSE"] = 36146 
    # h => {"FALSE"=>{:name=>"FALSE1", "FALSE"=>36146}} 

在将enum的每个其他元素传入块后,我们有:

h 
    #=> {"FALSE"=>{:name=>"FALSE1", "FALSE2"=>36146, "TRUE2"=>2607}, 
    # "TRUE"=> {:name=>"TRUE1", "FALSE2"=>2614, "TRUE2"=>1692}} 

的最后一步是提取这个散列值:

h.values 
    #=> [{:name=>"FALSE1", "FALSE2"=>36146, "TRUE2"=>2607}, 
    # {:name=>"TRUE1", "FALSE2"=>2614, "TRUE2"=>1692}] 
+0

each_with_object的大用例。感谢您的及时回应。 – deniz 2014-11-05 16:12:12