Help with inject, using hash array

I can’t quite figure out how to set up the inject command to do what I
want. (or if it’s even possible)

What I’m trying to do:

Create a list of categories from a search of the items table. Count how
many of each category appeared, and output that to the view.

This is the code I have so far:

@categories = @items.collect{|item| [“name”=>item.category.name,
?> “id”=>item.category.id]}
=> [[{“name”=>“Cat 1”, “id”=>1}], [{“name”=>“Cat 2”, “id”=>2}],
[{“name”=>“Cat 2”, “id”=>2}], [{“name”=>“Cat 3”, “id”=>3}]]

I’m trying to use a modified version of this > list.inject(Hash.new(0))
{ |h, x| h[x] += 1; h}< to create a @categories containing “name”, “id”
and “count”.

This is a sample of many things I have tried. (I clearly don’t
understand how this command works)

@categories.inject(Hash.new(0)) {|cat| [“name”=>cat.name, “id”=>cat.id,
“count”=>cat.count += 1]}

Any help appreciated.

Lance

At this point, I’m guessing that the collect statment isn’t getting the
data in a useful format…

Any Ideas?

try

@category_counts = Hash.new(0)
@items.collect { |item| item.category }.each { |cat|
@category_counts[cat.name] += 1 }

this will give you something like

{“cat1” => 3, “cat2” => 5, “cat3” => 10}

in @category_counts

Thanks for the input.

Tried using that, and my

@categories = @items.collect{|item| [“name”=>item.category.name,
“id”=>item.category.id]}

Code with this view code:

<% if @categories -%>
<% @categories.each do |cat| %>

 <%=
cat.name %>

<% if @category_counts -%>
<%= @category_counts[cat.name]%>
<% end -%>


<% end %>
<% end -%>

And as I suspected my @categories if not properly formated… :frowning:
I have sofar been unable to format it anyother way…

Lance S. wrote:

I can’t quite figure out how to set up the inject command to do what I
want. (or if it’s even possible)

(I clearly don’t understand how this command works)

I’m not sure how you ultimately want your data formated, but it’s true
you don’t understand how inject works.

I’ll try and explain it.

Inject is basically an accumulator method. Here’s a simple example…

[ 5, 10, 15 ].inject(0) { |sum, i| sum += i } # 30

First, inject operates on a collection, as you’re doing, so you’re good
there. Second, the argument to inject (zero) is given to the variable
sum. Third, the first value in your collection (5) is given the variable
i. We then add sum and i together. Sum is essentially the sum of our
entire operation.

But you can use inject for other things. It mostly depends on what your
enumerating over, and what you assign to the first variable in the
pipes.

Example of adding to an array…

[ ‘rabbit’, ‘bunny’, 5 ].inject([]) { |sum, i| sum << i } # [ ‘rabbit’,
‘bunny’, 5 ]

In this case we ended up with exactly what we put in, but that’s okay.
I’m just showing you how you can use inject.

Hopefully that helps. =)

Thank you for a very clear explination of how inject works.

I’m sure it will be of help, after I figure out how to fix my collect
problem.