Tom Cheung Tom Cheung - 5 months ago 36
JSON Question

How to use ruby uniq on nested array/hash

I am trying to call the uniq method on the follow json so that it would only return unique result base on 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) }


However, I am only getting this result

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


Instead of what I want

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


Am I using the correct method to output the result I want?

Answer

Here is one way to do this, in order to return the modified input hash, we can use uniq! which will modify the array a[:results] in place. We use dup to duplicate the hash a to preserve it, and then use tap to operate on duplicated hash.

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