Reputation: 5563
I've written a tool to count frequency of word pairs in a text, such that for each time word B follows word A, the count of words[A][B] is incremented.
In perl, the hash and hash of hashes gets automatically instantiated the first time you try to access it, which makes the code simple. In Javascript, it seems that you must first create the innards, which makes the code longer.
In Coffeescript, this functions:
class Adder
...
addPair: (word1, word2) ->
@count[word1] = {} if not @count[word1]?
@count[word1][word2] = 0 if not @count[word1][word2]?
++@count[word1][word2]
but it's two extra lines of 'defensive' code. Is there a way to do this more compactly, so I can maintain less code?
(Putting it in a trinary statement doesn't really make it more compact, just fewer characters for the same amount of logic.)
Upvotes: 1
Views: 56
Reputation: 19229
You can reduce the verbosity of those lines by using the or=
operator (or ?=
, but it's not necessary in these case):
addPair: (word1, word2) ->
@count[word1] or= {}
@count[word1][word2] or= 0
@count[word1][word2] += 1
You can also golf those two initialization lines into one (though i think this results in less readable code):
addPair: (word1, word2) ->
(@count[word1] or= {})[word2] or= 0
@count[word1][word2] += 1
By the way, supporting this kind of automatic object creation is known as autovivification, and has been discussed on the CoffeeScript issues. Also, Coco, a CS-derived language, has it :)
Upvotes: 1