Reputation: 1019
What i'd like to do is push a bunch of user inputted strings, separated by their spaces to Hash Keys and assign each of those Keys a numerical value from 0 upwards in their order of input. For example;
User input: "a s d f b"
Result:
a => 0
b => 1
c => 2
d => 3
f => 4
b => 5
But my code is only outputting 0 with no increment, please see my code below;
puts "Please enter data:"
text = gets.chomp
words = text.split(" ")
frequencies = Hash.new(0)
words.each do |k|
frequencies[k] += 1
end
frequencies.each do |x,y|
puts x + " " + y.to_s
end
Can anyone see what's wrong with the code above?
Upvotes: 3
Views: 1612
Reputation: 304147
frequencies
seems to be a poor choice of variable name from the description.
Any reason why you can't just
words = "foo bar baz"
=> "foo bar baz"
words.split.map.with_index.to_h
=> {"foo"=>0, "bar"=>1, "baz"=>2}
Upvotes: 0
Reputation: 22325
Your code doesn't work because
frequencies[k] += 1
Is like
frequencies[k] = frequencies[k] + 1
# ^ set new value ^ get default value (i.e. 0)
The default value never changes, so every key gets the same default value of 0 and adds one to it.
You could explicitly increment the default value each time
words.each do |k|
frequencies[k] = frequencies.default += 1
end
But I think the more Rubyish solution is to use the indices of the keys (since that's what the "numerical values" are). each_with_index
gives you each key with it's corresponding index, and to_h
turns these pairs into a Hash.
frequencies = text.split.each_with_index.to_h
egwspiti is correct that older versions of Ruby don't have Enumerable#to_h
. In that case you can do
words.each_with_index do |k, i|
frequencies[k] = i
end
Upvotes: 1
Reputation: 122383
The default value of every key in this Hash
is 0
, so by
frequencies[k] += 1
You are incrementing every value (of non-existing key) from 0
to 1
.
A simple fix is to use an external counter as the value:
counter = 0
words.each do |k|
frequencies[k] = counter
counter += 1
end
Upvotes: 2