2016-06-28 43 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}}]}   
相关问题