From: Charles Calvert Date: 2008-03-28T11:44:54+09:00 Subject: Re: numbers of a record in an array On Tue, 25 Mar 2008 05:23:50 -0500, Robert Klemme wrote: > 2008/3/25, Jes炭s Gabriel y Gal叩n : >> On Tue, Mar 25, 2008 at 10:09 AM, Bu Mihai 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. -- Charles Calvert | Software Design/Development Celtic Wolf, Inc. | Project Management http://www.celticwolf.com/ | Technical Writing (703) 580-0210 | Research