0

If I have two candidates and five voters, and the results of tendency to vote are:

[
  [:John, :Clinton, -27],
  [:John, :Bush, -8],
  [:Raphael, :Clinton, -12],
  [:Raphael, :Bush, -40],
  [:Damon, :Clinton, 71],
  [:Damon, :Bush, 4],
  [:Elysee, :Clinton, 13], 
  [:Elysee, :Bush, -36],
  [:Griffin, :Clinton, -1],
  [:Griffin, :Bush, 11]
]

How do I look at each voter, and count the largest Tendency number as a vote for that candidate and store it in a variable for the final tally of votes per candidate?

Hello! And thanks so much for the responses. Not only am I new to programming, I'm also new to Stackoverflow so forgive me if I'm not editing properly.

Apologies.

Reading what you guys put, I don't even know what to do with them, so I'll put the code I came up with and try to explain better what am trying to achieve. Bear with me.

If I have:

def stump_speech
  voter_list = {
    John: "Progressive",
    Raphael: "Conservative",
    Damon: "Libertarian",
    Elysee: "Independent",
    Griffin: "Massachussetts Democrat"
  }
end

and comparing it to:

candidate_list = {}
  candidate_list = {
    Clinton: "Democrat",
    Bush: "Republican",
}

and what runs it is:

voter_list.each { |voter_name, politics|
candidate_list.each { |candidate_name, party|
  if
    politics == "Progressive" && party == "Republican"
    voting_prob = rand(0..100) - 25
    decision
  elsif
    politics == "Progressive" && party == "Democrat"
    voting_prob = rand(0..100) - 75
    decision
  elsif
    politics == "Conservative" && party == "Republican"
    voting_prob = rand(0..100) - 75
    decision
  elsif
    politics == "Conservative" && party == "Democrat"
    voting_prob = rand(0..100) - 25
    decision
  elsif
    politics == "Independent" && party == "Republican"
    voting_prob = rand(0..100) - 50
    decision
  elsif
    politics == "Independent" && party == "Democrat"
    voting_prob = rand(0..100) - 50
    decision
  elsif
    politics == "Libertarian" && party == "Republican"
    voting_prob = rand(0..100) - 90
    decision
  elsif
    politics == "Libertarian" && party == "Democrat"
    voting_prob = rand(0..100) - 10
    decision
  elsif
    politics == "Massachussetts Democrat" && party == "Republican"
    voting_prob = rand(0..100) - 10
    decision
  elsif
    politics == "Massachussetts Democrat" && party == "Democrat"
    voting_prob = rand(0..100) - 90
    decision
  else
  end
}
}

And it outputs the array above earlier posted, how do I grab the numbers, John's, example, so that it will count as a vote for Bush, and Raphael's for Clinton, etc., and throw those into an array I could play with for the final tally in determining the winner?

In the simplest way you can manage, please? Thanks so much! I'm ten days into this and even grasping concepts isn't easy yet - hoping not to get discouraged.

jmanikan
  • 37
  • 2
  • What does your desired output look like? – Anthony Jul 11 '15 at 11:27
  • Welcome to Ruby and StackOverflow. Please clarify your problem a bit. You have given us a list of individual arrays, not a hash with key/value pairs. Please [edit] your question and add the output you desire for the given input. Also, if you've tried anything it is best to show what you've tried, even if it doesn't work. That helps us understand where you're stuck. – Mark Thomas Jul 11 '15 at 14:30
  • I took the liberty of making the input a valid Ruby array, removing references to a hash, and cleaning up the language a bit. I think it will be more clear to the answerers what you're looking for. – Mark Thomas Jul 11 '15 at 14:48

2 Answers2

1

Starting with the following array of arrays:

tendencies = [
  [:John, :Clinton, -27],
  [:John, :Bush, -8],
  [:Raphael, :Clinton, -12],
  [:Raphael, :Bush, -40],
  [:Damon, :Clinton, 71],
  [:Damon, :Bush, 4],
  [:Elysee, :Clinton, 13], 
  [:Elysee, :Bush, -36],
  [:Griffin, :Clinton, -1],
  [:Griffin, :Bush, 11]
]

First, I would use Enumerable's group_by to organize by voter, the first entry in each array.

tendencies.group_by {|t| t.first}

or, equivalently,

tendencies.group_by(&:first)

This results in the following hash:

{
  :John    =>[[:John, :Clinton, -27], [:John, :Bush, -8]],
  :Raphael =>[[:Raphael, :Clinton, -12], [:Raphael, :Bush, -40]]
  :Damon   =>[[:Damon, :Clinton, 71], [:Damon, :Bush, 4]],
  :Elysee  =>[[:Elysee, :Clinton, 13], [:Elysee, :Bush, -36]],
  :Griffin =>[[:Griffin, :Clinton, -1], [:Griffin, :Bush, 11]]
}

Now, I'm assuming that you want one candidate per voter. So if we look at each of the values above there are two options and we want the one with the max. Since we want one candidate per value, we can use map. for example, to get the Bush votes only, we can do the following:

tendencies.group_by(&:first).values.map(&:last)

This takes the last (second) subarray from each line above:

[
  [:John, :Bush, -8],
  [:Raphael, :Bush, -40],
  [:Damon, :Bush, 4],
  [:Elysee, :Bush, -36],
  [:Griffin, :Bush, 11]
]

But we don't want this, do we? We want the one with the max Tendency value. So we need to use max_by. This will take the max based on any criteria we specify, in this case the last value of each subarray (the Tendency).

tendencies.group_by(&:first).values.map{ |v| v.max_by(&:last)}

Result:

[
 [:John, :Bush, -8],
 [:Raphael, :Clinton, -12],
 [:Damon, :Clinton, 71],
 [:Elysee, :Clinton, 13],
 [:Griffin, :Bush, 11]
]

Getting closer! You can simply grab the middle value (index [1]) of the result using another map:

tendencies.group_by(&:first).values.map{ |v| v.max_by(&:last)}.map{ |v| v[1]}

Result: [:Bush, :Clinton, :Clinton, :Clinton, :Bush]

Now it just depends on how you want to represent this final tally. Let's say you want counts per candidate. There are a few ways to do it, but I'm going to use what we've used above, a group_by and a map.

votes = [:Bush, :Clinton, :Clinton, :Clinton, :Bush]

votes.group_by{|v| v}

# => {:Bush=>[:Bush, :Bush], :Clinton=>[:Clinton, :Clinton, :Clinton]}

votes.group_by{|v| v}.map{|candidate, votes| [candidate, votes.count]}

# => [[:Bush, 2], [:Clinton, 3]]
Community
  • 1
  • 1
Mark Thomas
  • 37,131
  • 11
  • 74
  • 101
0
array = 
[[:John, :Clinton, -27],
[:John, :Bush, -8],
[:Raphael, :Clinton, -12],
[:Raphael, :Bush, -40],
[:Damon, :Clinton, 71],
[:Damon, :Bush, 4],
[:Elysee, :Clinton, 13],
[:Elysee, :Bush, -36],
[:Griffin, :Clinton, -1],
[:Griffin, :Bush, 11]]

To look at John's do:

array.select { |rec| rec[0] == :John } # => [[:John, :Clinton, -27], [:John, :Bush, -8]]

Or to get the Total votes for Bush

vote_sum = 0
array.select { |rec| rec[1] == :Bush }.each { |rec| vote_sum += rec[-1] }

Note that sum is available in Rails but not plain Ruby (you could also use inject)

Dan Draper
  • 1,013
  • 9
  • 15