On Mon, Jan 16, 2012 at 10:05 PM, Abinoam Jr. <abinoam / gmail.com> wrote:
> On Mon, Jan 16, 2012 at 9:22 PM, Abinoam Jr. <abinoam / gmail.com> wrote:
>> On Mon, Jan 16, 2012 at 1:48 PM, Magnus Holm <judofyr / gmail.com> wrote:
>>> On Mon, Jan 16, 2012 at 17:04, Adam Prescott <adam / aprescott.com> wrote=
:
>>>> On Mon, Jan 16, 2012 at 16:00, Sigurd <cu9ypd / gmail.com> wrote:
>>>>
>>>>> [4,5,6,4,5,6,6,7].inject(Hash.new(0)) {|res, x| res[x] +=3D 1; res }
>>>>>
>>>>
>>>> I think this is a misuse of inject, personally, every time I see it. I=
t's
>>>> harder to read and it doesn't give the feeling of actually "reducing"
>>>> (inject's alias) the array down to one thing. The required `; res` is =
a
>>>> sign of that. Compare:
>>>>
>>>> [1, 2, 3, 4].inject(5) { |a, b| a + b }
>>>
>>> There's always each_with_object, although it's a little long:
>>>
>>> =A0[4,5,6,4,5,6,6,7].each_with_object(Hash.new(0)) { |x, res| res[x] +=
=3D 1 }
>>>
>>
>> I think Magnus Holm is the clearest (IMHO, yes, it's just a taste and
>> humble opinion.).
>>
>> [4,5,6,4,5,6,6,7].each_with_object(Hash.new(0)) {|num, hsh| hsh[num] +=
=3D 1}
>>
>> Another way (not better) I remember is...
>>
>> Hash[ [4,5,6,4,5,6,6,7].sort.chunk {|n| n}.map {|ix, els| [ix, els.size]=
 } ]
>>
>> See: http://ruby-doc.org/core-1.9.3/Enumerable.html#method-i-chunk
>>
>> It also can be... clearer?!?
>>
>> Hash[ [4,5,6,4,5,6,6,7].group_by {|n| n}.map {|ix, els| [ix, els.size] }=
 ]
>>
>> Perhaps something like this (same as Magnus Holm) just hiding the
>> complexity into the method.
>>
>> class Array
>> =A0def totalize_to_hash
>> =A0 =A0hsh =3D Hash.new(0)
>> =A0 =A0self.each do |n|
>> =A0 =A0 =A0hsh[n] +=3D 1
>> =A0 =A0end
>> =A0 =A0hsh
>> =A0end
>> end
>>
>> [4,5,6,4,5,6,6,7].totalize_to_hash
>>
>> Abinoam Jr.
>
> Some benchmark results...
>
> n =3D 100_000
> Benchmark.bm(15) do |b|
> =A0b.report("Ralph Shneiver:") { n.times { a =3D [4,5,6,4,5,6,6,7];
> result =3D Hash.new(0); a.each { |x| =A0result[x] +=3D 1 }; result} }
> =A0b.report("Sigurd:") =A0 =A0 =A0 =A0{ n.times {
> [4,5,6,4,5,6,6,7].inject(Hash.new(0)) {|res, x| res[x] +=3D 1; res } } }
> =A0b.report("Keinich #1") =A0 =A0 { n.times { Hash[a.group_by{|n|n}.map{|=
k,
> v|[k, v.size]}] } }
> =A0b.report("Keinich #2") =A0 =A0 { n.times {
> Hash.new(0).tap{|h|a.each{|n|h[n] +=3D 1}} } }
> =A0b.report("Magnus Holm:") =A0 { n.times {
> [4,5,6,4,5,6,6,7].each_with_object(Hash.new(0)) { |x, res| res[x] +=3D 1
> } } }
> =A0b.report("Abinoam #1:") =A0 =A0{ n.times { Hash[
> [4,5,6,4,5,6,6,7].sort.chunk {|n| n}.map {|ix, els| [ix, els.size] } ]
> } }
> end
>
> =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 user =A0 =A0 system =A0 =A0 =A0to=
tal =A0 =A0 =A0 =A0real
> Ralph Shneiver: =A0 0.290000 =A0 0.000000 =A0 0.290000 ( =A00.259640)
> Sigurd: =A0 =A0 =A0 =A0 =A00.320000 =A0 0.000000 =A0 0.320000 ( =A00.2898=
73)
> Keinich #1 =A0 =A0 =A0 0.560000 =A0 0.000000 =A0 0.560000 ( =A00.497736)
> Keinich #2 =A0 =A0 =A0 0.280000 =A0 0.000000 =A0 0.280000 ( =A00.250843)
> Magnus Holm: =A0 =A0 0.310000 =A0 0.000000 =A0 0.310000 ( =A00.283344)
> Abinoam #1: =A0 =A0 =A01.140000 =A0 0.000000 =A0 1.140000 ( =A01.042744)
>
> Abinoam Jr.
>

Sorry for the mess... (some error in the bench code + horrible text wrappin=
g)

Apologizing with the gist...
https://gist.github.com/1624016

Abinoam Jr.