Numbers of a record in an array

a have an array array=["a","b","c","a","b"]
how can i find the numbers of "a", "b","c" items in the array?

···

--
Posted via http://www.ruby-forum.com/.

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 += 1}
=> ["a", "b", "a", "c", "b", "a", "c", "c"]
irb(main):009:0> h
=> {"a"=>3, "b"=>2, "c"=>3}

Hope this helps,

Jesus.

···

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?

If you install the facets gem you can use "frequency"

e.g.

irb

irb:> require 'rubygems'
=> false
irb:> require 'facets'
=> true
irb:> x = %w[a b d e e rkeke ele e ee e e el d]
=> ["a", "b", "d", "e", "e", "rkeke", "ele", "e", "ee", "e", "e", "el",
"d"]
irb:> x.frequency
=> {"ee"=>1, "a"=>1, "b"=>1, "d"=>2, "e"=>5, "el"=>1, "ele"=>1,
"rkeke"=>1}

···

-----Original Message-----
From: list-bounce@example.com [mailto:list-bounce@example.com] On Behalf
Of Bu Mihai
Sent: Tuesday, March 25, 2008 5:09 AM
To: ruby-talk ML
Subject: numbers of a record in an array

a have an array array=["a","b","c","a","b"]
how can i find the numbers of "a", "b","c" items in the array?
--
Posted via http://www.ruby-forum.com/\.

This email and any attached files are confidential and intended solely for the intended recipient(s). If you are not the named recipient you should not read, distribute, copy or alter this email. Any views or opinions expressed in this email are those of the author and do not represent those of the company. Warning: Although precautions have been taken to make sure no viruses are present in this email, the company cannot accept responsibility for any loss or damage that arise from the use of this email or attachments.

Here's another

irb(main):001:0> a = %w{a b a c b a c c}
=> ["a", "b", "a", "c", "b", "a", "c", "c"]
irb(main):002:0> a.inject(Hash.new(0)){|cnt,e| cnt[e]+=1; cnt}
=> {"a"=>3, "b"=>2, "c"=>3}

Jesús, note that you do not need the block form of Hash.new because of
the way + works. It is sufficient to make 0 the default element.

Kind regards

robert

···

2008/3/25, Jesús Gabriel y Galán <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 += 1}
=> ["a", "b", "a", "c", "b", "a", "c", "c"]
irb(main):009:0> h
=> {"a"=>3, "b"=>2, "c"=>3}

--
use.inject do |as, often| as.you_can - without end

Paul Danese wrote:

If you install the facets gem you can use "frequency"

e.g.

irb

irb:> require 'rubygems'
=> false
irb:> require 'facets'
=> true
irb:> x = %w[a b d e e rkeke ele e ee e e el d]
=> ["a", "b", "d", "e", "e", "rkeke", "ele", "e", "ee", "e", "e", "el",
"d"]
irb:> x.frequency
=> {"ee"=>1, "a"=>1, "b"=>1, "d"=>2, "e"=>5, "el"=>1, "ele"=>1,
"rkeke"=>1}

Tnx a lot for this gem, it looks very interesting not just for solving
this issue.

···

--
Posted via http://www.ruby-forum.com/\.

I installed facets 2.4.0 (the current latest) and tried to use the
'frequency' method shown in this example, but in doesn't exist in this
version of facets.

I did 'ri facets' and it only returned 'Enumerable#frequency'
This is using Linux (PCLOS) and Ruby 1.8.6-p114.

What version of facets does the 'frequency' method exist in, because
it isn't in version 2.4.0?

···

On Mar 27, 10:51 am, Paul Danese <pdan...@Rib-x.com> wrote:

If you install the facets gem you can use "frequency"

e.g.

>irb

irb:> require 'rubygems'
=> false
irb:> require 'facets'
=> true
irb:> x = %w[a b d e e rkeke ele e ee e e el d]
=> ["a", "b", "d", "e", "e", "rkeke", "ele", "e", "ee", "e", "e", "el",
"d"]
irb:> x.frequency
=> {"ee"=>1, "a"=>1, "b"=>1, "d"=>2, "e"=>5, "el"=>1, "ele"=>1,
"rkeke"=>1}

Oh, that's right. I'm so used to that form for defaulting to an array :-).
You say the reason is because of how + works, but is it not the reason
the fact that 0 is an immediate value
of which there's only one instance? So having the same reference to
the 0 object works, whereas having the same
reference to an array (for example) wouldn't achieve the desired effect?

Thanks,

Jesus.

···

On Tue, Mar 25, 2008 at 11:23 AM, Robert Klemme <shortcutter@googlemail.com> wrote:

2008/3/25, Jesús Gabriel y Galán <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?
> 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 += 1}
> => ["a", "b", "a", "c", "b", "a", "c", "c"]
> irb(main):009:0> h
> => {"a"=>3, "b"=>2, "c"=>3}

Here's another

irb(main):001:0> a = %w{a b a c b a c c}

=> ["a", "b", "a", "c", "b", "a", "c", "c"]
irb(main):002:0> a.inject(Hash.new(0)){|cnt,e| cnt[e]+=1; cnt}

=> {"a"=>3, "b"=>2, "c"=>3}

Jesús, note that you do not need the block form of Hash.new because of
the way + works. It is sufficient to make 0 the default element.

> 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 += 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

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.

···

On Tue, 25 Mar 2008 05:23:50 -0500, Robert Klemme wrote:

2008/3/25, Jesús Gabriel y Galán <jgabrielygalan@gmail.com>:

On Tue, Mar 25, 2008 at 10:09 AM, Bu Mihai <mihai.bulhac@yahoo.com> wrote:

          from :0

--
Charles Calvert | Software Design/Development
Celtic Wolf, Inc. | Project Management
http://www.celticwolf.com/ | Technical Writing
(703) 580-0210 | Research

Correction:
I did 'ri frequency' NOT 'ri facets'

···

On Mar 28, 11:39 am, jzakiya <jzak...@mail.com> wrote:

On Mar 27, 10:51 am, Paul Danese <pdan...@Rib-x.com> wrote:

> If you install the facets gem you can use "frequency"

> e.g.

> >irb

> irb:> require 'rubygems'
> => false
> irb:> require 'facets'
> => true
> irb:> x = %w[a b d e e rkeke ele e ee e e el d]
> => ["a", "b", "d", "e", "e", "rkeke", "ele", "e", "ee", "e", "e", "el",
> "d"]
> irb:> x.frequency
> => {"ee"=>1, "a"=>1, "b"=>1, "d"=>2, "e"=>5, "el"=>1, "ele"=>1,
> "rkeke"=>1}

I installed facets 2.4.0 (the current latest) and tried to use the
'frequency' method shown in this example, but in doesn't exist in this
version of facets.

I did 'ri facets' and it only returned 'Enumerable#frequency'
This is using Linux (PCLOS) and Ruby 1.8.6-p114.

What version of facets does the 'frequency' method exist in, because
it isn't in version 2.4.0?

OK, I found what is going on with facets and the 'frequency' method.

In facets 2.3.0 (2008/2/18) 'frequency' is a method under Enumerable,
which got loaded by doing

require 'rubygems'
require 'facets'

The current facets 2.4.0 (2008/3/24) 'frequency' has been moved to the
'probability.rb' file under
the Enumerable module. So to load 'frequency' under facets 2.4.0 you
must do

require 'rubygems'
require 'facets/enumerable/probability.rb'

I would consider this a bug for breaking prior usage (by hiding the
method in probability.rb).

If you go to http://rubyforge.org/frs/?group_id=804&release_id=20470
and download the tar/zip files for each version you can see the
changes.

This is the facets source for 'frequency'

def frequency
    #probs = Hash.new(0)
    #each do |e|
    # probs[e] += 1
    #end
    #probs
    inject(Hash.new(0)){|h,v| h[v]+=1; h}
  end

···

On Mar 28, 11:39 am, jzakiya <jzak...@mail.com> wrote:

On Mar 27, 10:51 am, Paul Danese <pdan...@Rib-x.com> wrote:

> If you install the facets gem you can use "frequency"

> e.g.

> >irb

> irb:> require 'rubygems'
> => false
> irb:> require 'facets'
> => true
> irb:> x = %w[a b d e e rkeke ele e ee e e el d]
> => ["a", "b", "d", "e", "e", "rkeke", "ele", "e", "ee", "e", "e", "el",
> "d"]
> irb:> x.frequency
> => {"ee"=>1, "a"=>1, "b"=>1, "d"=>2, "e"=>5, "el"=>1, "ele"=>1,
> "rkeke"=>1}

I installed facets 2.4.0 (the current latest) and tried to use the
'frequency' method shown in this example, but in doesn't exist in this
version of facets.

I did 'ri facets' and it only returned 'Enumerable#frequency'
This is using Linux (PCLOS) and Ruby 1.8.6-p114.

What version of facets does the 'frequency' method exist in, because
it isn't in version 2.4.0?

Frequency exists in 2.4.0, but there appear to be some path problems w/
2.4.0.

Try uninstalling 2.4.0 and installing 2.3.0 instead.

···

-----Original Message-----
From: jzakiya [mailto:jzakiya@mail.com]
Sent: Friday, March 28, 2008 11:40 AM
To: ruby-talk ML
Subject: Re: numbers of a record in an array

On Mar 27, 10:51 am, Paul Danese <pdan...@Rib-x.com> wrote:

If you install the facets gem you can use "frequency"

e.g.

>irb

irb:> require 'rubygems'
=> false
irb:> require 'facets'
=> true
irb:> x = %w[a b d e e rkeke ele e ee e e el d]
=> ["a", "b", "d", "e", "e", "rkeke", "ele", "e", "ee", "e", "e",

"el",

"d"]
irb:> x.frequency
=> {"ee"=>1, "a"=>1, "b"=>1, "d"=>2, "e"=>5, "el"=>1, "ele"=>1,
"rkeke"=>1}

I installed facets 2.4.0 (the current latest) and tried to use the
'frequency' method shown in this example, but in doesn't exist in this
version of facets.

I did 'ri facets' and it only returned 'Enumerable#frequency'
This is using Linux (PCLOS) and Ruby 1.8.6-p114.

What version of facets does the 'frequency' method exist in, because
it isn't in version 2.4.0?

This email and any attached files are confidential and intended solely for the intended recipient(s). If you are not the named recipient you should not read, distribute, copy or alter this email. Any views or opinions expressed in this email are those of the author and do not represent those of the company. Warning: Although precautions have been taken to make sure no viruses are present in this email, the company cannot accept responsibility for any loss or damage that arise from the use of this email or attachments.

No, this has nothing to do with immediate values. The reason why this
works is that an operation is used that creates a new instance
(Fixnum#+ in this case) and uses assignment to place a new value on
every iteration. This also works with arrays and other non immediate
and even mutable instances:

irb(main):001:0> collector = Hash.new
=> {}
irb(main):002:0> 10.times {|i| collector[i%3] += [i]}
=> 10
irb(main):003:0> collector
=> {0=>[0, 3, 6, 9], 1=>[1, 4, 7], 2=>[2, 5, 8]}

You can even freeze the default object

irb(main):007:0> collector = Hash.new(.freeze)
=> {}
irb(main):008:0> 10.times {|i| collector[i%3] += [i]}
=> 10
irb(main):009:0> collector
=> {0=>[0, 3, 6, 9], 1=>[1, 4, 7], 2=>[2, 5, 8]}

Kind regards

robert

···

2008/3/25, Jesús Gabriel y Galán <jgabrielygalan@gmail.com>:

On Tue, Mar 25, 2008 at 11:23 AM, Robert Klemme > <shortcutter@googlemail.com> wrote:
> 2008/3/25, Jesús Gabriel y Galán <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?

> > 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 += 1}
> > => ["a", "b", "a", "c", "b", "a", "c", "c"]
> > irb(main):009:0> h
> > => {"a"=>3, "b"=>2, "c"=>3}
>
> Here's another
>
> irb(main):001:0> a = %w{a b a c b a c c}
>
> => ["a", "b", "a", "c", "b", "a", "c", "c"]
> irb(main):002:0> a.inject(Hash.new(0)){|cnt,e| cnt[e]+=1; cnt}
>
> => {"a"=>3, "b"=>2, "c"=>3}
>
> Jesús, note that you do not need the block form of Hash.new because of
> the way + works. It is sufficient to make 0 the default element.

Oh, that's right. I'm so used to that form for defaulting to an array :-).
You say the reason is because of how + works, but is it not the reason
the fact that 0 is an immediate value
of which there's only one instance? So having the same reference to
the 0 object works, whereas having the same
reference to an array (for example) wouldn't achieve the desired effect?

--
use.inject do |as, often| as.you_can - without end

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

···

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ús Gabriel y Galán <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 += 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.

> 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 += 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.

Probably just a spelling error: it should read "for each e in a ...". Your pseudo code has it actually correct.

I would pseudocode it as this:

cnt = Hash.new(0)
foreach (e in a)
{
  cnt[e] += 1
}

Btw, it's not far from pseudo code to Ruby code:

irb(main):003:0> cnt = Hash.new 0
=> {}
irb(main):004:0> for e in a do
irb(main):005:1* cnt[e] += 1
irb(main):006:1> end
=> ["a", "b", "a", "c", "b", "a", "c", "c"]
irb(main):007:0> cnt
=> {"a"=>3, "b"=>2, "c"=>3}
irb(main):008:0>

:slight_smile:

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.

As Todd said, the return value of the block is the next iteration's accumulator:

irb(main):009:0> (1..5).inject(0) {|*a| p a;a.first+10}
[0, 1]
[10, 2]
[20, 3]
[30, 4]
[40, 5]
=> 50

This allows elegant code, as in

irb(main):010:0> (1..5).inject(0){|s,x| s+x}
=> 15

which would not work if s was the same instance for every iteration.

Kind regards

  robert

···

On 28.03.2008 03:41, Charles Calvert wrote:

On Tue, 25 Mar 2008 05:23:50 -0500, Robert Klemme wrote:

2008/3/25, Jesús Gabriel y Galán <jgabrielygalan@gmail.com>:

On Tue, Mar 25, 2008 at 10:09 AM, Bu Mihai <mihai.bulhac@yahoo.com> wrote:

A faster(running time) way is this

def freq2(a)
a_sorted=a.sort;temp=0;h=Hash.new(0);
a_sorted.uniq.each{|x|
     h=a_sorted.rindex(x)+1-temp;
    temp+=h
}
end

I did a small test and this method seems to running 5 times faster than the
inject one!

start=Time.now; 1000.times{|x| freq1(a*x)}; stop=Time.now; puts

stop-start
16.413787

start=Time.now; 1000.times{|x| freq2(a*x)}; stop=Time.now; puts

stop-start
3.17855

This seemed counter intuitive as freq2 is doing a lot more than freq1.
Is inject that slow (or have I done something wrong)???

Piyush

···

On Fri, Mar 28, 2008 at 11:55 PM, jzakiya <jzakiya@mail.com> wrote:

On Mar 28, 11:39 am, jzakiya <jzak...@mail.com> wrote:
> On Mar 27, 10:51 am, Paul Danese <pdan...@Rib-x.com> wrote:
>
>
>
> > If you install the facets gem you can use "frequency"
>
> > e.g.
>
> > >irb
>
> > irb:> require 'rubygems'
> > => false
> > irb:> require 'facets'
> > => true
> > irb:> x = %w[a b d e e rkeke ele e ee e e el d]
> > => ["a", "b", "d", "e", "e", "rkeke", "ele", "e", "ee", "e", "e",
"el",
> > "d"]
> > irb:> x.frequency
> > => {"ee"=>1, "a"=>1, "b"=>1, "d"=>2, "e"=>5, "el"=>1, "ele"=>1,
> > "rkeke"=>1}
>
> I installed facets 2.4.0 (the current latest) and tried to use the
> 'frequency' method shown in this example, but in doesn't exist in this
> version of facets.
>
> I did 'ri facets' and it only returned 'Enumerable#frequency'
> This is using Linux (PCLOS) and Ruby 1.8.6-p114.
>
> What version of facets does the 'frequency' method exist in, because
> it isn't in version 2.4.0?

Correction:
I did 'ri frequency' NOT 'ri facets'

Ah, ok, now I see what you mean. I didn't consider this case, because
you are creating intermediate arrays every iteration. In my head I was
equating the += for Fixnums with << for Arrays in this idiom, if you see
what I mean.

Thanks,

Jesus.

···

On Tue, Mar 25, 2008 at 1:49 PM, Robert Klemme <shortcutter@googlemail.com> wrote:

2008/3/25, Jesús Gabriel y Galán <jgabrielygalan@gmail.com>:
> On Tue, Mar 25, 2008 at 11:23 AM, Robert Klemme > > <shortcutter@googlemail.com> wrote:

No, this has nothing to do with immediate values. The reason why this
works is that an operation is used that creates a new instance
(Fixnum#+ in this case) and uses assignment to place a new value on
every iteration. This also works with arrays and other non immediate
and even mutable instances:

irb(main):001:0> collector = Hash.new
=> {}
irb(main):002:0> 10.times {|i| collector[i%3] += [i]}
=> 10

That's what I would usually do. But you asked for the reason why the
default value setting was sufficient. So I demonstrated with a
mutable object and + - could have been anything else (BigDecimal#+ or
String#+ for example).

Cheers

robert

···

2008/3/25, Jesús Gabriel y Galán <jgabrielygalan@gmail.com>:

On Tue, Mar 25, 2008 at 1:49 PM, Robert Klemme > > <shortcutter@googlemail.com> wrote:
> 2008/3/25, Jesús Gabriel y Galán <jgabrielygalan@gmail.com>:
> > On Tue, Mar 25, 2008 at 11:23 AM, Robert Klemme > > > <shortcutter@googlemail.com> wrote:

> No, this has nothing to do with immediate values. The reason why this
> works is that an operation is used that creates a new instance
> (Fixnum#+ in this case) and uses assignment to place a new value on
> every iteration. This also works with arrays and other non immediate
> and even mutable instances:
>
> irb(main):001:0> collector = Hash.new
> => {}
> irb(main):002:0> 10.times {|i| collector[i%3] += [i]}
> => 10

Ah, ok, now I see what you mean. I didn't consider this case, because
you are creating intermediate arrays every iteration. In my head I was
equating the += for Fixnums with << for Arrays in this idiom, if you see
what I mean.

--
use.inject do |as, often| as.you_can - without end