Reputation: 13
My ruby script filters a log and generates a hash like this
scores = {"Rahul" => "273", "John"=> "202", "coventry" => "194"}
by skipping multiple values for a key which is obvious
log file will be like this
Rahul has 273 Rahul has 217 John has 202 Coventry has 194
Is it Possible to generate something like this
scores = {"Rahul" => "273", "Rahul" =>"217",
"John"=> "202", "coventry" => "194"}
scores = {"Rahul" => "273","217",
"John"=> "202", "coventry" => "194"}
Is there a way to forcefully write into a hash even though the key is already existing in the hash
I will be grateful to any help or suggestions
Upvotes: 0
Views: 3003
Reputation: 114158
To store your scores, you could create a hash which has an empty array as its default value:
scores = Hash.new { |hash, key| hash[key] = [] }
scores['Rahul'] #=> [] <- a fresh and empty array
You can now extract the values from the log and add it to the respective key's value. I'm using scan
with a block: (using the pattern from mudasobwa's answer)
log = 'Rahul has 273 Rahul has 217 John has 202 Coventry has 194'
log.scan(/(\w+) has (\d+)/) { |name, score| scores[name] << score.to_i }
scores #=> {"Rahul"=>[273, 217], "John"=>[202], "Coventry"=>[194]}
Although not required, I've converted each score to an integer before adding it to the array.
Upvotes: 1
Reputation: 121000
"Rahul has 273 Rahul has 217 John has 202 Coventry has 194".
scan(/(\w+) has (\d+)/).group_by(&:shift)
#⇒ {"Rahul"=>[["273"], ["217"]],
# "John"=>[["202"]],
# "Coventry"=>[["194"]]}
For the values flattening please check the comment by Johan Wentholt below.
Upvotes: 4