Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Ruby, unique hashes in array based on multiple fields

Tags:

arrays

ruby

I'd like to get back an array of hashes based on sport and type combination

I've got the following array:

[
    { sport: "football", type: 11, other_key: 5 }, 
    { sport: "football", type: 12, othey_key: 100  },
    { sport: "football", type: 11, othey_key: 700  },
    { sport: "basketball", type: 11, othey_key: 200 },
    { sport: "basketball", type: 11, othey_key: 500 }
]

I'd like to get back:

[
    { sport: "football", type: 11, other_key: 5 }, 
    { sport: "football", type: 12, othey_key: 100  },
    { sport: "basketball", type: 11, othey_key: 200 },
]

I tried to use (pseudocode):

[{}, {}, {}].uniq { |m| m.sport and m.type }

I know I can create such array with loops, I'm quite new to ruby and I'm curious if there's a better (more elegant) way to do it.

like image 934
Emil A. Avatar asked Sep 18 '14 18:09

Emil A.


3 Answers

Try using Array#values_at to generate an array to uniq by.

sports.uniq{ |s| s.values_at(:sport, :type) }
like image 57
Kyle Avatar answered Nov 10 '22 06:11

Kyle


One solution is to build some sort of key with the sport and type, like so:

arr.uniq{ |m| "#{m[:sport]}-#{m[:type]}" }

The way uniq works is that it uses the return value of the block to compare elements.

like image 21
mbillard Avatar answered Nov 10 '22 08:11

mbillard


require 'pp'

data = [
    { sport: "football", type: 11, other_key: 5 }, 
    { sport: "football", type: 12, othey_key: 100  },
    { sport: "football", type: 11, othey_key: 700  },
    { sport: "basketball", type: 11, othey_key: 200 },
    { sport: "basketball", type: 11, othey_key: 500 }
]

results = data.uniq do |hash|
  [hash[:sport], hash[:type]]
end

pp results

--output:--
[{:sport=>"football", :type=>11, :other_key=>5},
 {:sport=>"football", :type=>12, :othey_key=>100},
 {:sport=>"basketball", :type=>11, :othey_key=>200}]
like image 40
7stud Avatar answered Nov 10 '22 08:11

7stud