Skip to content

Instantly share code, notes, and snippets.

@TalkativeTree
Last active December 15, 2015 11:08
Show Gist options
  • Save TalkativeTree/5250592 to your computer and use it in GitHub Desktop.
Save TalkativeTree/5250592 to your computer and use it in GitHub Desktop.
Need to figure out the mode of an array, if two elements tie for the mode, must output all of the tying elements.
def mode(array)
freq = array.inject(Hash.new(0)) { |h,v| h[v] += 1; h }
max = freq.values.max
freq.select { |k, f|; (f==max) }.map {|k, f| k}
end
mode([1,2,2,3,3,4])
#Explanation of method order of processing method(array)
#freq = array.inject(Hash.new(0)) { |h,v| h[v] += 1; h }
######puts freq.inspect
###### => {1=>1, 2=>2, 3=>2, 4=>1}
#Breakdown:
# 1. array.inject(Hash.new(0))
# This is using the the method new from the Hash class to create an empyty method,
# which by itself would result in nil
# 2. { |h, v| h[v] += 1; h}
# This is the block and |h, v| are you're parameters. So for our array=[1,2,2,3,3,4], we are going to iterate each
# element through this block. The results are going to be placed into the new Hash we're injecting into the Arra
# Iteration 1 Iteration 2 Iteration 3 Iteration 4 Iteration 5 Iteration 6
# For 1: for 2 for 2 for 3 for 3 for 4
# h = 1, h = 2 h = 2 h = 3 h = 3 h = 1
# h[v] += 1 => v =1 h[v] += 1 => v = 1 h[v] += => v =2 h[v] += 1 => 1 h[v] += => 2 h[v] += => 1
#
# The hash that is being created will look like this at each pass through
# Pass 1 Pass 2 Pass 3 Pass 4 Pass 5 Past 6
# {1 => 1} {1 => 1, 2 =>1} {1 => 1, 2=>2} {1 => 1,2=>2,3=>1} {1 => 1,2=>2,3=>2} {1 => 1,2=>2,3=>2,4=>1}
#Which is why we get the following:
######puts freq.inspect
###### => {1=>1, 2=>2, 3=>2, 4=>1}
# max = freq.values.max
##### puts max
##### => 2
#Breakdown:
# The purpose of max is to find the max values.
# 1. .values method -- comes from ENV, which is a hash-like accessor for environmental variables http://ruby-doc.org/core-2.0/ENV.html#method-c-values
# I am not too familar with ENV, but in this case I assume the environment is our hash and our variables are h
# and we are grabbing the values of h.
# 2. .max method-- simply grabs the max value and puts it into the nice variable max.
# ergo: max = 2
# freq.select { |k, f|; (f==max) }.map {|k, f| k}
# Take a look at these to see how the select functions differently with different blocks
#####puts freq.select { |k, f|; k}
##### => {1=>1, 2=>2, 3=>2, 4=>1}\
#####puts freq.select { |k, f|; (f==max) }
##### => {2 => 2, 3 => 3}
#####puts freq.select { |k, f|; (f==max) }.map {|k, f| k}.inspect
##### => [2, 3]
#Breakdown:
# We are selecting from the hash freq the variables with the max values.
# rememebr freq.inspect => {1=>1, 2=>2, 3=>2, 4=>1
# .select { |k, f|; (f==max) }
# I should have kept them consistant, but in this situation k = h and f = v
# when (f==max) (or f == 2) is true, we are taking that |k, f| and putting it into our temp hash
# Iteration 1 Iteration 2 Iteration 3 Iteration 4
# k == 1 k == 2 k == 3 k == 4
# f == 1 f == 2 f == 2 f == 1
# false true true false
# doesn't pass through passes through passes through doesn't pass through
# {} {2 => 2} {2=> 2, 3 => 3} {2=> 2, 3 => 3}
########puts
######## => {2 => 2, 3 => 3}
#Breakdown:
# OKay, so what does the ".map {|k, f| k}.inspect" do?
#This is what we use to remove our value and return only our mode (or modes), or in this instance k.
#so we've done freq.select { |k, f|; (f==max) } and received {2 => 2, 3 => 3}.
#Now we're going to do {2 => 2, 3 => 3}.map {|k, f| k}.inspect, but there are only TWO passes this time. Whew less typing!
# but first, if you're not familiar with map, check it out http://ruby-doc.org/core-2.0/Enumerable.html#method-i-map
# map return an array (in this case our list of mode/s) that is a result of passing block once on each element of the enumerable
# if you're like me and are still wonderinf WTF an enumerable is...use Google :P
# kidding, this may help https://practicingruby.com/articles/shared/eislpkhxolnr or http://ruby-doc.org/core-2.0/Enumerable.html
#{2 => 2, 3 => 3}.map {|k, f| k}.inspect
# Iteration 1 Iteration 2
# k = 2 k = 3
# f = 2 f = 2
# => 2 => 3
# [2] [2,3]
# at this point, you don't have to do .inspect, but I wanted to print it out as
# => [2,3]
#and not
# => 2
# => 3
#end
#mode([1,2,2,3,3,4])
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment