newbie
newbie

Reputation: 1033

ruby count based on certain combination

I have data in the following format

"stats": {
    "team": [],
    "outcome": [],
    "rank": []
}

I need to determine if there is a combination of 2 or more results present from the above structure then print something.

So the idea is:

(if stats.team.present? && if stats.outcome.present) || (if stats.outcome.present? && if stats.rank.present) || (if stats.team.present? && if stats.rank.present)

A better way is to create a method to add a counter that its incremented if the team, outcome, rank has a count of greater than 0.

And then check if the counter is greater than 2. Eg:

def my_count
  count = 0

  count += 1 if stats.team.count > 0
  count += 1 if stats.outcome.count > 0
  count += 1 if stats.rank.count > 0

  if count > 1
    return true
  end
end

Are these the only 2 options or is there a cleaner way?

Upvotes: 2

Views: 227

Answers (5)

user229044
user229044

Reputation: 239240

Are these the only 2 options or is there a cleaner way?

A ton of cleaner ways, but the best ones will use many?, part of ActiveSupport.

many? is essentially like any?, but instead of asking if "one or more" meet a condition, it asks if two or more. It's by far the most semantically correct implementation of your question:

stats = { team: [], outcome: [], rank: [] }}

stats.many? { |k,v| v.present? } # false

stats = { team: [1], outcome: [1], rank: [] }}

stats.many? { |k,v| v.present? } # true

You can get slightly more clever with stats.values and Symbol#to_proc to shorten this further, but I don't see the need:

stats.values.many?(&:present?)

Upvotes: 2

Arup Rakshit
Arup Rakshit

Reputation: 118261

You can do as

data = {"stats" => { "team" => [], "outcome" => [1], "rank" => [] }}
if data["stats"].values.count([]) > 1
    #code
end

Upvotes: 0

Luiz E.
Luiz E.

Reputation: 7229

You can try map/reduce and can read more here

after map/reduce you can check the output to see if there are any combination

Upvotes: -1

Zippie
Zippie

Reputation: 6088

No need to transform it into an array:

data = {stats: { team: [], outcome: [], rank: [] }}

if data[:stats].reject{|k,v| v.empty?}.size > 1

Upvotes: 1

Alex Teut
Alex Teut

Reputation: 844

First of all, is it hash or object? I will think of hash.

According to your question: some kind of MapReduce may be looking better:

["team", "outcome", "rank"].map{|key| stats[key].present? }.count(true) > 1

Upvotes: -1

Related Questions