Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Pushing a string into an array within an array yields unexpected result

Tags:

ruby

I have an array in Ruby that consists of 5 empty arrays. I am trying to use the << operator to push a string into the first array, but the result is that the string gets pushed into ALL of the arrays. Please help me understand this.

The expected output is:

# => [["car"], [], [], [], []]

but instead I get:

# => [["car"], ["car"], ["car"], ["car"], ["car"]]

irb dump:

1.9.3-p194 :001 > output = Array.new(5, [])
 => [[], [], [], [], []] 
1.9.3-p194 :002 > output.inspect
 => "[[], [], [], [], []]" 
1.9.3-p194 :003 > output[0].inspect
 => "[]" 
1.9.3-p194 :004 > output[0] << "car"
 => ["car"] 
1.9.3-p194 :005 > output.inspect
 => "[[\"car\"], [\"car\"], [\"car\"], [\"car\"], [\"car\"]]" 
like image 559
will_d Avatar asked May 31 '12 03:05

will_d


People also ask

How do you push two items in an array?

Use the Array. push() method to push multiple values to an array, e.g. arr. push('b', 'c', 'd'); . The push() method adds one or more values to the end of an array.

How do you convert a comma separated string to an array?

Method 1: Using split() method The split() method is used to split a string on the basis of a separator. This separator could be defined as a comma to separate the string whenever a comma is encountered. This method returns an array of strings that are separated.

Which method can you use character other than comma to separate values from array?

The split() method returns the new array. The split() method does not change the original string. If (" ") is used as separator, the string is split between words.

How can you create an array in JavaScript using array literal?

Creating an Array Using an array literal is the easiest way to create a JavaScript Array. Syntax: const array_name = [item1, item2, ...]; It is a common practice to declare arrays with the const keyword.


2 Answers

They're all the same object:

ree-1.8.7-2012.02 :001 > output = Array.new(5, [])
 => [[], [], [], [], []] 
ree-1.8.7-2012.02 :002 > output[0]
 => [] 
ree-1.8.7-2012.02 :003 > output[0].object_id
 => 2219989240 
ree-1.8.7-2012.02 :004 > output[1].object_id
 => 2219989240 
ree-1.8.7-2012.02 :005 > output[2].object_id
 => 2219989240 
ree-1.8.7-2012.02 :006 > output[3].object_id
 => 2219989240 
ree-1.8.7-2012.02 :007 > output[4].object_id
 => 2219989240 
ree-1.8.7-2012.02 :008 > 

Try this:

ree-1.8.7-2012.02 :008 > output = []
 => [] 
ree-1.8.7-2012.02 :009 > 5.times{output << []}
 => 5 
like image 150
Pedro Nascimento Avatar answered Sep 30 '22 16:09

Pedro Nascimento


They all have the same object id, as pointed out by Pedro Nascimento, if the arrays are initialized in that manner. You can get around this by using a similar syntax to create your nested arrays:

irb(main):047:0> output = Array.new(5) {[]}
=> [[], [], [], [], []]
irb(main):048:0> output.each {|i| puts i.object_id}
10941700
10941680
10941660
10941640
10941620

So your append to output[0] will work as expected:

irb(main):049:0> output[0] << "cat"
=> ["cat"]
irb(main):050:0> output
=> [["cat"], [], [], [], []]
like image 21
Makoto Avatar answered Sep 30 '22 16:09

Makoto