Reputation: 148
I'm passing a hash to this function that either a) has keys that are strings along with values that are ints OR b) it is an empty hash. The point of the function is to return nil if the hash is empty and return the key associated with the lowest int.
def key_for_min_value(name_hash)
if name_hash == nil
return nil
else
lowest_value = nil
lowest_value_name = nil
name_hash.collect do |name, value|
if lowest_value > value
lowest_value = value
lowest_value_name = name
end
end
return lowest_value_name
end
end
The error I'm receiving is:
1) smallest hash value does not call the `#keys` method
Failure/Error: key_for_min_value(hash)
NoMethodError:
undefined method `>' for nil:NilClass`
Upvotes: 2
Views: 190
Reputation: 211540
You can't compare nil
to anything using >
, it's not allowed, so you either have to avoid that test or use tools like min_by
to get the right value instead of this collect
approach.
One way to make your unit test happy might be:
def key_for_min_value(name_hash)
return unless (name_hash)
name_hash.keys.min_by do |key|
name_hash[key]
end
end
Ruby leans very heavily on the Enumerable library, there's a tool in there for nearly every job, so when you have some free time have a look around there, lots of things to discover.
Now Ruby is very strict about comparisons, and in particular a nil
value can't be "compared" (e.g. >
or <
and such) to other values. You'll need to populate that minimum with the first value by default, not nil
, then the comparisons work out, but doing that completely is pretty ugly:
def key_for_min_value(name_hash)
return unless (name_hash)
min_key, min_value = name_hash.first
name_hash.each do |key, value|
next unless (value < min_value)
min_key = key
min_value = value
end
min_key
end
So that approach is really not worth it. Enumerable makes it way easier and as a bonus your intent is clear. One thing you'll come to appreciate is that in Ruby if your code looks like code then you're probably going about it the wrong way, over-complicating things.
Ruby is an unusually expressive language, and often there's a very minimal form to express just about anything.
Upvotes: 4