2016-06-28 42 views
1

我想呼籲後續JSON的uniq的方法,以便它只會在EMPLOYEE_ID返回唯一結果的基礎如何使用Ruby的uniq在嵌套數組/哈希

# Json array 
a ={ 
    results: [ 
    { 
    employee: { 
     name: "A", 
     employee_id: "A-00016", 
     title: 1 
    } 
    },{ 
    employee: { 
     name: "A", 
     employee_id: "A-00016", 
     title: 2 
    } 
    },{ 
    employee: { 
     name: "C", 
     employee_id: "C-00017", 
     title: 3 
    } 
    } 
    ] 
    } 



# Calling uniq on a 
a.uniq { |p| p.values_at(:employee_id) } 

不過,我只得到這個結果

{ 
    results: [ 
    { 
    employee: { 
     name: "A", 
     employee_id: "A-00016", 
     title: 1 
    } 
    } 
    ] 
    } 

而不是我想要的

{ 
    results: [ 
    { 
    employee: { 
     name: "A", 
     employee_id: "A-00016", 
     title: 1 
    },{ 
    employee: { 
     name: "C", 
     employee_id: "C-00017", 
     title: 3 
    } 
    } 
    ] 
    } 

現在用正確的方法來輸出的I我想要的結果?

+0

我會推薦做:'a [:results] .uniq!',但是第一個實例中title = 1,第二個中title = 2。所以,紅寶石會認爲這兩個不同。 – oliviergg

回答

1

下面是要做到這一點,爲了返回修改的輸入hash,我們可以使用一個方式uniq!這將修改數組a[:results]在適當位置。我們使用dup複製散列a以保留它,然後使用tap對重複散列進行操作。

r = a.dup.tap do |h| 
    h[:results].uniq! do |h| 
    h[:employee][:employee_id] 
    end 
end 

#=> {:results=> 
# [ 
#  {:employee=>{:name=>"A", :employee_id=>"A-00016", :title=>1}}, 
#  {:employee=>{:name=>"C", :employee_id=>"C-00017", :title=>3}} 
# ] 
# } 
+0

謝謝!該方法的工作原理,但我投了@mudasobwa答案,因爲它使用uniq。 –

+0

@TomCheung其他答案不會產生所需的輸出。這個解決方案使用'uniq!'來獲得想要的輸出 –

+0

湯姆,魔杖有一點。 –

3

隨着uniq

input[:results].uniq { |e| e[:employee][:employee_id] } 
#⇒ [ 
# {:employee=>{:name=>"A", :employee_id=>"A-00016", :title=>"1"}}, 
# {:employee=>{:name=>"C", :employee_id=>"C-00017", :title=>"3"}}] 

但我相信應該適用什麼就由具有相同id兄弟姐妹選擇一些條件。下面的代碼選擇所述一箇中,具有最大title值:

input[:results].group_by { |e| e[:employee][:employee_id] } 
       .map { |_, v| v.max_by { |e| e[:employee][:title].to_i } } 
#⇒ [ 
# {:employee=>{:name=>"A", :employee_id=>"A-00016", :title=>"2"}}, 
# {:employee=>{:name=>"C", :employee_id=>"C-00017", :title=>"3"}}] 
1
def selection_criterion(h) 
    h[:title].to_i 
end 

{results: a[:results].group_by {|h| h[:employee][:employee_id]}. 
         values. 
         map {|arr| arr.max_by {|h| selection_criterion(h[:employee])}}} 
    #=> {:results=> 
    #  [{:employee=>{:name=>"A", :employee_id=>"A-00016", :title=>2}}, 
    #  {:employee=>{:name=>"C", :employee_id=>"C-00017", :title=>3}}]}   

定義selection_criterion如需要的話,和可能的變更max_bymin_by

步驟如下。

b = a[:results] 
    # => [{:employee=>{:name=>"A", :employee_id=>"A-00016", :title=>1}}, 
    #  {:employee=>{:name=>"A", :employee_id=>"A-00016", :title=>2}}, 
    #  {:employee=>{:name=>"C", :employee_id=>"C-00017", :title=>3}}] 
c = b.group_by { |h| h[:employee][:employee_id] } 
    #=> {"A-00016"=>[{:employee=>{:name=>"A", :employee_id=>"A-00016", :title=>1}}, 
    #    {:employee=>{:name=>"A", :employee_id=>"A-00016", :title=>2}}], 
    # "C-00017"=>[{:employee=>{:name=>"C", :employee_id=>"C-00017", :title=>3}}]} 
d = c.values 
    #=> [[{:employee=>{:name=>"A", :employee_id=>"A-00016", :title=>1}}, 
    #  {:employee=>{:name=>"A", :employee_id=>"A-00016", :title=>2}}], 
    # [{:employee=>{:name=>"C", :employee_id=>"C-00017", :title=>3}}]] 
e = d.map { |arr| arr.max_by { |h| selection_criterion(h[:employee]) } } 
    #=> [{:employee=>{:name=>"A", :employee_id=>"A-00016", :title=>2}}, 
    # {:employee=>{:name=>"C", :employee_id=>"C-00017", :title=>3}}] 
{ results: e } 
    #=> {:results=> 
    #  [{:employee=>{:name=>"A", :employee_id=>"A-00016", :title=>2}}, 
    #  {:employee=>{:name=>"C", :employee_id=>"C-00017", :title=>3}}]}   
相關問題