13

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.

1
  • Yes, uniq with a block is the way to go, but here's another way: arr.group_by { |h| [h[:sport],h[:type]] }.values.map(&:first). Commented Sep 19, 2014 at 1:15

3 Answers 3

24

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

sports.uniq{ |s| s.values_at(:sport, :type) }
Sign up to request clarification or add additional context in comments.

1 Comment

Just a tiny correction: uniq is passing in each value to the block, so that's actually a Hash in this case and it would be calling Hash#values_at. Just be careful if you have an array of things other than hashes or arrays.
7

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.

Comments

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

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.