ironsand
ironsand

Reputation: 15161

How to select hashes from array of hashes that appears more than 2 times by a specified key

I want to select companies when their code appears more than 2 times.

companies = [{code: 10, value: 3}, {code: 3, value: 5}, {code: 10, value: 4}, {code: 5, value: 10}]

companies.select{|c| companies.select{|c_inside| c_inside[:code] == c[:code]}.count > 1 }
=> [{:code=>10, :value=>3}, {:code=>10, :value=>4}]

This code works, but it seems a bit redundant. Is there better way to write the function like this?

Upvotes: 0

Views: 37

Answers (3)

etdev
etdev

Reputation: 534

Here's another option:

companies.group_by{ |hsh| hsh[:code] }
  .values
  .select{ |val| val.count > 1 }
  .flatten

#=> [{:code=>10, :value=>3}, {:code=>10, :value=>4}]

Upvotes: 2

sschmeck
sschmeck

Reputation: 7705

Just another way.

companies.group_by { |e| e[:code] }
         .select { |_, v| v.size > 1 }
         .flat_map { |_, v| v }
#=> [{:code=>10, :value=>3}, {:code=>10, :value=>4}]

Upvotes: 1

Raman
Raman

Reputation: 1281

This code uses a n iterations instead of n^2 iterations:

companies = [{code: 10, value: 3}, {code: 3, value: 5}, {code: 10, value: 4}, {code: 5, value: 10}]
final_value = []
companies.each.with_object({}) do |c, hash|
  hash[c[:code]] = [] if hash[c[:code]] == nil
  hash[c[:code]] << c
  if hash[c[:code]].count == 2
    final_value += hash[c[:code]]
  elsif hash[c[:code]].count > 2
    final_value << c
  end
end

puts final_value

Upvotes: 1

Related Questions