bytebiscuit
bytebiscuit

Reputation: 3496

modifying inner hashes in ruby

I'm trying to do the following say;

I have a hash: {"word1" => {"doc1" => 1, "doc2" => 1}}

Now when I insert a new word in the hash I pass the word itself with a document id e.g. word2 and doc2 that should give me:

{"word1" => {"doc1" => 1, "doc2" =>1}, "word2" => {"doc2" => 1}}

If I now add: word1 and doc1 it should give me:

{"word1" => {"doc1" => 2, "doc2" =>1}, "word2" => {"doc2" => 1}}

Note: doc1's value has increased by 1

and for word2 and doc2

{"word1" => {"doc1" => 2, "doc2" =>1}, "word2" => {"doc2" => 2}}

also if add a new doc3 to say word2 it should give me:

{"word1" => {"doc1" => 2, "doc2" =>1}, "word2" => {"doc2" => 2, "doc3" => 1}}

How do I achieve this !?

Upvotes: 2

Views: 65

Answers (2)

Niklas B.
Niklas B.

Reputation: 95318

irb(main):005:0> words = Hash.new { |h,k| h[k] = Hash.new(0) }
irb(main):006:0> words["word1"]["doc1"] += 1
irb(main):007:0> words["word1"]["doc1"] += 1
irb(main):008:0> words["word2"]["doc2"] += 1
irb(main):009:0> words
=> {"word1"=>{"doc1"=>2}, "word2"=>{"doc2"=>1}}

Of course you can encapsulate that into a function if you want.

Upvotes: 2

DigitalRoss
DigitalRoss

Reputation: 146123

@h = {}

def addword word, doc
  inner = @h[word] || {}
  @h[word] = inner.merge(doc => (inner[doc] || 0) + 1)
  p [:hash_is_now, @h]
end

addword 'word1', 'doc1'
addword 'word1', 'doc2'
addword 'word2', 'doc2'
addword 'word1', 'doc1'
addword 'word2', 'doc2'
addword 'word2', 'doc3'

Upvotes: 1

Related Questions