On Thu, Mar 27, 2008 at 9:44 PM, Charles Calvert <cbciv / yahoo.com> wrote:
> On Tue, 25 Mar 2008 05:23:50 -0500, Robert Klemme wrote:
>
>  > 2008/3/25, Jesù¸ Gabriel y GaláÏ <jgabrielygalan / gmail.com>:
>
> >> On Tue, Mar 25, 2008 at 10:09 AM, Bu Mihai <mihai.bulhac / yahoo.com> wrote:
>
> >>  > a have an array array=["a","b","c","a","b"]
>  >>  >  how can i find the numbers of "a", "b","c" items in the array?
>  >>
>  >>
>  >> Here's one way:
>
> >>
>  >>  irb(main):006:0> a = %w{a b a c b a c c}
>  >>  => ["a", "b", "a", "c", "b", "a", "c", "c"]
>  >>  irb(main):007:0> h = Hash.new {|h,k| h[k] = 0}
>  >>  => {}
>  >>  irb(main):008:0> a.each {|x| h[x] += 1}
>  >>  => ["a", "b", "a", "c", "b", "a", "c", "c"]
>  >>  irb(main):009:0> h
>  >>  => {"a"=>3, "b"=>2, "c"=>3}
>  >
>  > Here's another
>
>  Let's see if I understand this:
>
>
>  > irb(main):001:0> a = %w{a b a c b a c c}
>  > => ["a", "b", "a", "c", "b", "a", "c", "c"]
>
>  Creates an array of strings.
>
>
>  > irb(main):002:0> a.inject(Hash.new(0)){|cnt,e| cnt[e]+=1; cnt}
>  > => {"a"=>3, "b"=>2, "c"=>3}
>
>  Calls the method Enumerable::inject on the variable a, passing Hash.new(0)
>  as the initial value of memo, which is the accumulator.  For each e in cnt
>  (which is a reference to the hash returned by "Hash.new"), it increments
>  the count whose key is the value of e.  I would pseudocode it as this:
>
>  cnt = Hash.new(0)
>  foreach (e in a)
>  {
>         cnt[e] += 1
>  }
>
>  What does the last "cnt" do, right before the closing brace, return a
>  reference to the hash? I tried removing that bit:
>
>
>         a.inject(Hash.new(0)){|cnt,e| cnt[e]+=1}
>
>  and got the error:
>
>         TypeError: can't convert String into Integer
>                 from (irb):2:in `[]'
>                 from (irb):2
>                 from (irb):2:in `inject'
>                 from (irb):2:in `each'
>                 from (irb):2:in `inject'
>                 from (irb):2
>                 from :0
>
>  I'm guessing that the use of "cnt" is controlling the interpretation of
>  the type returned by cnt[e], but I don't understand how.

You need to "inject" a Hash back into the block on each iteration,
which is the result of the block, which is the result of the last
statement inside the block.

If you leave that out...

h = a.inject(Hash.new(0)) {|k,v| k[v] += 1}

...the next injection will be the result of the block, which will be
1, so on the next go around, you would be trying to...

1["a"] += 1

...and thus the string error.

hth,
Todd