Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

using inject to count elements in array

I'm trying to count the occurrences of elements in an array and save it in a hash. I'd like to use the inject function. I have this code:

a = ["the","the","a", "it", "it", "it"]
a.inject(Hash.new(0)) {|hash,word| hash[word] += 1}

I don't understand why I get the following error:

TypeError: can't convert String into Integer
    from (irb):47:in `[]'
    from (irb):47:in `block in irb_binding'
    from (irb):47:in `each'
    from (irb):47:in `inject'

Also, I don't know how to fix it.

like image 362
Selah Avatar asked May 31 '13 15:05

Selah


People also ask

How do you count elements in an array?

Array#count() : count() is a Array class method which returns the number of elements in the array. It can also find the total number of a particular element in the array. Syntax: Array. count() Parameter: obj - specific element to found Return: removes all the nil values from the array.

What does .inject do in Ruby?

The #inject method acts the same as the #reduce method, and they are considered aliases. These enumerator methods can take a range or array of numbers, and can optionally receive a block. When called, the inject method will pass each element and accumulate each sequentially.


1 Answers

inject calls your block with two parameters, memo and current element. It then takes return value of the block and replaces memo with it. Your block returns integers. So, after first iteratation, your memo is not a hash anymore, it's an integer. And integers don't accept strings in their indexers.

Fix is easy, just return hash from the block.

a = ["the","the","a", "it", "it", "it"]
a.inject(Hash.new(0)) {|hash,word| hash[word] += 1; hash }

You may prefer each_with_object because it doesn't replace memo. Note that each_with_object accepts parameters in reverse (element first, memo second).

a.each_with_object(Hash.new(0)) {|word, hash| hash[word] += 1}
like image 152
Sergio Tulentsev Avatar answered Oct 13 '22 09:10

Sergio Tulentsev