【问题标题】:How to use ruby uniq on nested array/hash如何在嵌套数组/哈希上使用 ruby​​ uniq
【发布时间】:2016-06-28 14:19:46
【问题描述】:

我正在尝试在后续 json 上调用 uniq 方法,以便它只返回基于 employee_id 的唯一结果

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

我是否使用正确的方法来输出我想要的结果?

【问题讨论】:

  • 我建议您这样做:a[:results].uniq! 但您的第一个实例为 title=1,第二个实例为 title=2。因此,ruby 会首先将两者视为不同。

标签: ruby-on-rails arrays ruby json hash


【解决方案1】:

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

【讨论】:

    【解决方案2】:

    这是一种方法,为了返回修改后的输入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}}
    #    ]
    #   }
    

    【讨论】:

    • 谢谢!该方法有效,但我投票给@mudasobwa 答案,因为它使用 uniq。
    • @TomCheung 其他答案不会产生所需的输出。此解决方案使用uniq! 来获得所需的输出
    【解决方案3】:
    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_by更改为min_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}}]}        
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2018-08-24
      • 1970-01-01
      • 1970-01-01
      • 2020-07-02
      • 2017-04-03
      • 2013-07-06
      • 2021-03-16
      • 2019-11-21
      相关资源
      最近更新 更多