# Is this array operation correct?

**URL:** <https://rubytalk.org/t/is-this-array-operation-correct/1186>\
**Category:** ruby-talk\
**Created:** [14 August 2002 01:59 UTC](https://rubytalk.org/t/is-this-array-operation-correct/1186 "2002-08-14T01:59:50Z")\
**Posts on this page:** 8\
**Page:** 1

<div class="post-metadata">

**Author:** ![Mauricio](https://avatars.discourse-cdn.com/v4/letter/m/90db22/32.png) [@Mauricio](https://rubytalk.org/u/Mauricio)\
**Post date:** [14 August 2002 01:59 UTC](https://rubytalk.org/t/is-this-array-operation-correct/1186/1 "2002-08-14T01:59:50Z")

</div>

Hi,

```
I've tried this:

```

a = Array.new(3,[]) =\> [[], [], []]  
a[1].push(3) =\> [[3],[3],[3]]

Is this correct? a[1].push(3) is the same as a[2].push(3)? If the  
constructor creates the same copy for all array elements, shouldn’t the  
array create copies when writing?

```
Thanks,
Maurício
```

---

<div class="post-metadata">

**Author:** ![David\_Alan\_Black1](https://avatars.discourse-cdn.com/v4/letter/d/278dde/32.png) [@David\_Alan\_Black1](https://rubytalk.org/u/David_Alan_Black1)\
**Post date:** [14 August 2002 02:38 UTC](https://rubytalk.org/t/is-this-array-operation-correct/1186/2 "2002-08-14T02:38:47Z")

</div>

Hello –

> Hi,
> 
> ```
> I've tried this:
> 
> ```
> 
> a = Array.new(3,) =\> [, ,]  
> a[1].push(3) =\> [[3],[3],[3]]
> 
> Is this correct? a[1].push(3) is the same as a[2].push(3)? If the  
> constructor creates the same copy for all array elements, shouldn’t the  
> array create copies when writing?

I’m not sure I follow the question, but the general thing going on is:  
a[0] and a[1] and a[2] are references to the same object, so if you  
change the object through one of those references, the change will be  
visible in all of them.

It’s as if you said:

ar =   
a = [ar, ar, ar]  
ar.push(3)

and then ‘a’ would look like: [[3],[3],[3]]

David

> **···**
>
> On Wed, 14 Aug 2002, Maurício wrote:
> 
> –  
> David Alan Black  
> home: [dblack@candle.superlink.net](mailto:dblack@candle.superlink.net)  
> work: blackdav@shu.edu  
> Web: [http://pirate.shu.edu/~blackdav](http://pirate.shu.edu/~blackdav)

---

<div class="post-metadata">

**Author:** ![Christian\_Boos](https://avatars.discourse-cdn.com/v4/letter/c/ce7236/32.png) [@Christian\_Boos](https://rubytalk.org/u/Christian_Boos)\
**Post date:** [14 August 2002 08:23 UTC](https://rubytalk.org/t/is-this-array-operation-correct/1186/3 "2002-08-14T08:23:36Z")

</div>

> From: [dblack@candle.superlink.net](mailto:dblack@candle.superlink.net) [[mailto:dblack@candle.superlink.net](mailto:dblack@candle.superlink.net)]  
> Sent: Wednesday, August 14, 2002 4:39 AM  
> To: ruby-talk ML  
> Subject: Re: Is this array operation correct?
> 
> Hello –
> 
> > Hi,
> > 
> > ```
> > I've tried this:
> > 
> > ```
> > 
> > a = Array.new(3,) =\> [, ,]  
> > a[1].push(3) =\> [[3],[3],[3]]

…

> It’s as if you said:
> 
> ar =   
> a = [ar, ar, ar]  
> ar.push(3)
> 
> and then ‘a’ would look like: [[3],[3],[3]]
> 
> >

Then, do something like:

Array.new(3).map { }

Is there something shorter/more efficient?

– Christian

> **···**
>
> > -----Original Message-----  
> > On Wed, 14 Aug 2002, Maurício wrote:

---

<div class="post-metadata">

**Author:** ![Mrchameleon](https://avatars.discourse-cdn.com/v4/letter/m/8e7dd6/32.png) [@Mrchameleon](https://rubytalk.org/u/Mrchameleon)\
**Post date:** [14 August 2002 08:31 UTC](https://rubytalk.org/t/is-this-array-operation-correct/1186/4 "2002-08-14T08:31:24Z")

</div>

> > ```
> > I've tried this:
> > 
> > ```
> > 
> > a = Array.new(3,) =\> [, ,]  
> > a[1].push(3) =\> [[3],[3],[3]]

You may be wanting this …

a = (0…3).collect { Array.new }  
a[1].push(3) =\> [,[3],]

Yours

Chris

---

<div class="post-metadata">

**Author:** ![ts1](https://avatars.discourse-cdn.com/v4/letter/t/a8b319/32.png) [@ts1](https://rubytalk.org/u/ts1)\
**Post date:** [14 August 2002 08:32 UTC](https://rubytalk.org/t/is-this-array-operation-correct/1186/5 "2002-08-14T08:32:58Z")

</div>

> Array.new(3).map { }

> Is there something shorter/more efficient?

With 1.7 you can give it a block

pigeon% ruby -ve 'a = Array.new(3) { }; a[1].push 1; p a'  
ruby 1.7.2 (2002-08-06) [i686-linux]  
[, [1], ]  
pigeon%

Guy Decoux

---

<div class="post-metadata">

**Author:** ![George\_Ogata1](https://avatars.discourse-cdn.com/v4/letter/g/d9b06d/32.png) [@George\_Ogata1](https://rubytalk.org/u/George_Ogata1)\
**Post date:** [15 August 2002 02:14 UTC](https://rubytalk.org/t/is-this-array-operation-correct/1186/6 "2002-08-15T02:14:07Z")

</div>

> Then, do something like:
> 
> Array.new(3).map { }
> 
> Is there something shorter/more efficient?

If you don’t like using Array.new, you can #map to a Range:

(1…3).map{}

(Dunno about efficiency, here.)

If you’re going to map to a fresh Array, though, you may as well use the  
in-place version:

Array.new(3).map!{}

---

<div class="post-metadata">

**Author:** ![Gavin\_Sinclair](https://avatars.discourse-cdn.com/v4/letter/g/db5fbb/32.png) [@Gavin\_Sinclair](https://rubytalk.org/u/Gavin_Sinclair)\
**Post date:** [15 August 2002 03:12 UTC](https://rubytalk.org/t/is-this-array-operation-correct/1186/7 "2002-08-15T03:12:24Z")

</div>

> > Then, do something like:
> > 
> > Array.new(3).map { }
> > 
> > Is there something shorter/more efficient?
> 
> If you don’t like using Array.new, you can #map to a Range:
> 
> (1…3).map{}
> 
> (Dunno about efficiency, here.)
> 
> If you’re going to map to a fresh Array, though, you may as well use the  
> in-place version:
> 
> Array.new(3).map!{}

Speaking from inexperience, I doubt there’s any significant efficiency  
difference between the two solutions mentioned above.

–Gavin

---

<div class="post-metadata">

**Author:** ![Christian\_Boos](https://avatars.discourse-cdn.com/v4/letter/c/ce7236/32.png) [@Christian\_Boos](https://rubytalk.org/u/Christian_Boos)\
**Post date:** [15 August 2002 07:08 UTC](https://rubytalk.org/t/is-this-array-operation-correct/1186/8 "2002-08-15T07:08:11Z")

</div>

# Really basic benchmarking (for 1.6.5 ) …

def time\_it  
GC.start  
now = Time.now  
yield  
Time.now - now  
end

time\_it { Array.new(100000).map {} }  
0.611  
time\_it { Array.new(100000).map {} }  
0.631  
time\_it { (1..100000).map {} }  
0.471  
time\_it { (1..100000).map {} }  
0.471  
time\_it { Array.new(100000).map! {} }  
0.351  
time\_it { Array.new(100000).map! {} }  
0.361

Using map! seems the fastest way, thanks for the tip!

– Christian

> **···**
>
> > -----Original Message-----  
> > From: George Ogata [[mailto:g\_ogata@optushome.com.au](mailto:g_ogata@optushome.com.au)]  
> > Sent: Thursday, August 15, 2002 4:14 AM  
> > To: ruby-talk ML  
> > Subject: RE: Is this array operation correct?
> > 
> > > Then, do something like:
> > > 
> > > Array.new(3).map { }
> > > 
> > > Is there something shorter/more efficient?
> > 
> > If you don’t like using Array.new, you can #map to a Range:
> > 
> > (1..3).map{}
> > 
> > (Dunno about efficiency, here.)
> > 
> > If you’re going to map to a fresh Array, though, you may as well use the  
> > in-place version:
> > 
> > Array.new(3).map!{}
