2014-11-04 2 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' 객체로 변환되어야합니다. 아이디어에 대한 제 대답을보십시오. –

+0

질문을 명확하게하려면 편집해야합니다. 내 이해가 정확하다면, "두 개의 해시 배열을 만들고 싶습니다. 첫 번째 해시에는': name => 'FALSE'와 두 개의 다른 키 - 값 쌍이 있습니다. 키 (값)는 hash [ "col1"]'의 값이 "FALSE"(여기서는'0'과'2'를 상쇄하므로)의 값의 오프셋에서'hash [ "col2"]'('hash [ "Freq"]' ''FALSE "=> 36146"'및''TRUE "=> 2607')가됩니다. 'hash [ "col1"]'의 원소가 "TRUE"와 같은 것을 제외하면 두 번째 해시도 비슷하게 구성됩니다 (여기서는 오프셋 1과 3에서). –

+0

수정 및 설명이 필요하다고 말하면 질문을 편집해야합니다. 현재 닫으려는 표가 3 개이므로 빨리 게시하십시오. –

답변

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], {}]] 

참고 그 후 요소의 해시 값 {} 각에 도시 된 (제) 요소가 블록으로 전달 될 때까지는 비어 있지 않습니다.

제 배열

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