Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Ruby on Rails: hash.each {} issues

Here is my code:

records_hash = records[:id].inject({}) { |result,h|
  if result.has_key?(h)
    result[h] += 1
  else
    result[h] = 1
  end
  result
}

@test2 = records_hash.each{|key,value| puts "#{key} is #{value}"}

My output should look like this:

bozo is 3
bubba is 4
bonker is 5

But it renders on the page (<%= @test2 %>) as this:

bozo3bubba4bonker5

I've tried .each_key & .each-value with similar blocks and they all return the same string above. I run the same code in IRB and it works as expected.

What am I doing wrong?

like image 747
neezer Avatar asked Jan 10 '09 04:01

neezer


People also ask

How do I iterate a Hash in Ruby?

Iterating over a Hash You can use the each method to iterate over all the elements in a Hash. However unlike Array#each , when you iterate over a Hash using each , it passes two values to the block: the key and the value of each element.

Are Ruby hashes ordered?

Hashes are inherently unordered. Hashes provide amortized O(1) insertion and retrieval of elements by key, and that's it. If you need an ordered set of pairs, use an array of arrays.

How do you check if something is a Hash Ruby?

Overview. A particular value can be checked to see if it exists in a certain hash by using the has_value?() method. This method returns true if such a value exists, otherwise false .

How do you add two hashes in Ruby?

We can merge two hashes using the merge() method. When using the merge() method: Each new entry is added to the end. Each duplicate-key entry's value overwrites the previous value.


1 Answers

Your problem is that you are using the each method to build your string. What you want is the map method. each method returns the hash and map returns the value of the block.

You want something like this:

@test2 = records_hash.map { |k,v| "#{k} is #{v}" }

Also, you shouldn't be building view code like this, unless it is a simple string. Your example implies you want each unique element on each line. So your view should be like this:

<% @records_hash.each do |k,v| %>
<%= "#{k} is #{v}" %>
<% end -%>

If your view is an HTML one, you'll want some separator between each line as well:

<% @records_hash.each do |k,v| %>
<%= "#{k} is #{v}" %><br/>
<% end -%>

or

<ul>
  <% @records_hash.each do |k,v| %>
  <li><%= "#{k} is #{v}" %></li>
  <% end -%>
</ul>
like image 60
Samuel Avatar answered Oct 09 '22 11:10

Samuel