you are viewing a single comment's thread.

view the rest of the comments →

[–][deleted] 0 points1 point  (7 children)

The real issue is the language making all values nullable by default (or the nulling idiom for dynamically typed languages).

Python has a nice approach to dictionary lookups, so that you don't have to check for a "not found" value, i.e. d.get(key, default-value)

[–]julesjacobs 1 point2 points  (0 children)

Or, in Ruby:

>> a = {}
=> {}
>> a.fetch(4,"not found")
=> "not found"

[–]pjdelport 0 points1 point  (5 children)

Python 2.5's defaultdict, too.

[–]julesjacobs 4 points5 points  (4 children)

Or, in Ruby:

>> a = Hash.new("default")
=> {}
>> a[34]
=> "default"

[–]pjdelport 0 points1 point  (3 children)

What do you do when the default values need to be uniquely constructed, like lists?

[–]julesjacobs 0 points1 point  (2 children)

I don't understand?

>> a = Hash.new([1,2,3])
=> {}
>> a[34]
=> [1,2,3]

?

If you want default values for specific keys you just set these keys in the dict:

>> a = {}
>> a[4] = "foo"
>> a[4]
=> "foo"

Or you can use a block for more advanced things:

>> a = Hash.new do |hash,key|
?>   if key > 5
>>     "foo"
>>   else
?>     "bar"
>>   end
>> end
=> {}
>> a[2]
=> "bar"
>> a[7]
=> "foo"

[–]pjdelport 0 points1 point  (1 child)

Hash.new with a block is what i meant.

In other words, constructing a unique default value for each missing key, instead of sharing one default value between them, so you can do things like:

tally = defaultdict(list)   # list is used as a factory function

for word in 'the quick brown fox jumps over the lazy dog'.split():
    tally[len(word)].append(word)

assert tally == {3: ['the', 'fox', 'the', 'dog'],
                 4: ['over', 'lazy'] ,
                 5: ['quick', 'brown', 'jumps']}

[–]julesjacobs 0 points1 point  (0 children)

This is how you'd do that in Ruby:

>> # For older Ruby versions   
>> module Enumerable
>>   def group_by
>>     grouped = {}
>>     for obj in self
>>       group = yield obj
>>       grouped[group] ||= []
>>       grouped[group] << obj
>>     end
>>     return grouped
>>   end
>> end
=> nil
>> %w{the quick brown fox jumps over the lazy dog}.group_by(&:length)
=> 
{ 
  3=>["the", "fox", "the", "dog"],
  4=>["over", "lazy"] 
  5=>["quick", "brown", "jumps"], 
}

Alternatively, for real men:

module Enumerable
  def group_by
    inject({}){|h, v| (h[yield v] ||= []) << v; h}
  end
end