2013-05-07 20 views
6

Ich habe mit Arrays ein wenig herumspielen, und fand ich in Schwierigkeiten den folgenden Code zu verstehen:Was ist der Unterschied zwischen << und + =?

first_array = [] 
second_array = [] 
third_array = []       # I initialized 3 empty arrays 

third_array << [1,2,3,4,5,6,7,8,9]  # I loaded 1..9 into third_array[0] 
puts third_array.size     # => 1 

first_array << third_array    # 1..9 was loaded into first_array[0] 

second_array += third_array    # 1..9 was loaded into second_array[0] 

puts first_array == third_array   # false 
puts second_array == third_array   # true 
puts first_array == second_array   # false 

puts first_array.size     # 1 
puts second_array.size     # 1 
puts third_array.size     # 1 

Was mit diesem passiert?

second_array += third_array    # I have no clue 

Warum sind nicht alle Arrays gleich?

Antwort

7

Sie zeigen ziemlich unterschiedliche Verhaltensweisen. Man erstellt und weist ein neues Objekt Array zu, das andere ändert ein vorhandenes Objekt.

+= wäre das gleiche wie second_array = second_array + third_array. Dies sendet die + Nachricht an das second_array Objekt, das third_array als Argument übergeben.

Per die Dokumentation Array.+ gibt ein neues Array-Objekt durch Verketten der beiden Arrays erstellt. Dies wird ein neues Objekt zurückgeben.

Array.<< drücken Sie einfach die Parameter an das Ende des existierenden Array-Objekt:

second_array = [] 
second_array.object_id = 1234 

second_array += [1,2,3,4] 
second_array.object_id = 5678 

second_array << 5 
second_array.object_id = 5678 

Es gibt auch einen Unterschied, wie der Parameter hinzugefügt wird. Durch die Zugabe von anderen Elementen, wird dazu beitragen, es zu sehen, warum Ihre Arrays nicht gleich sind:

second_array = [1, 2, 3] 

# This will push the entire object, in this case an array 
second_array << [1,2] 
# => [1, 2, 3, [1,2]] 

# Specifically appends the individual elements, 
# not the entire array object 
second_array + [4, 5] 
# => [1, 2, 3, [1,2], 4, 5] 

Dies liegt daran, Array.+ Verkettung statt Schieben verwendet. Im Gegensatz zu Array.concat, das das vorhandene Objekt ändert, gibt Array.+ ein neues Objekt zurück.

Sie eine Ruby-Implementierung denken können, wie:

class Array 
    def +(other_arr) 
    dup.concat(other_arr) 
    end 
end 

In Ihrem speziellen Beispiel sehen Sie Ihre Objekte wie dies am Ende:

first_array = [[[1, 2, 3, 4, 5, 6, 7, 8, 9]]] # [] << [] << (1..9).to_a 
second_array = [[1, 2, 3, 4, 5, 6, 7, 8, 9]] # [] + ([] << (1..9).to_a) 
third_array = [[1, 2, 3, 4, 5, 6, 7, 8, 9]] # [] << (1..9).to_a 
+2

Also Ihr Punkt Ist das für second_array ein neues Array erstellt, das ungleich dem dritten Array ist, auch wenn der Inhalt der beiden Arrays identisch ist? – nzs

+0

THAT @codedad ist immer noch nicht beantwortet! hat jemand ein Verständnis dafür? – rubybrah

+0

second_array ist gleich dem dritten_array (aber es hat ein neues Objekt erstellt), das Originalbeispiel zeigt dies. der first_array ist nicht gleich –

3

<< anhängen, ein Element zu einem Array

+= fügt ein Array zu einem Array hinzu.

Beispiele:

[1,2] << 3 # returns [1,2,3]

[1,2] += [3,4] # returns [1,2,3,4]

+6

Ihr Beispiel für '<<' wäre besser, wenn Sie zeigen würden, dass [1,2] << [3,4] 'produziert '[1,2, [3,4]]' IMHO. – squiguy

+0

@squiguy Sie haben Recht. und Teddy, Du meinst, dass in meinem Beispiel first_array = [1,2,3,4,5,6,7,8,9] und second_array = [[1,2,3,4,5,6,7], 8,9]]? ist das richtig? – rubybrah

+1

@rubybrah nicht. 'third_array' ist' [[1..9]] ',' first_array' ist '[[[1..9]]]' und 'second_array' ist' [[1..9]] ' –

3

Der letzte Unterschied nicht so weit zwischen << erwähnt und += ist, dass << Verfahren ist:

class Array 
    def << other 
    # performs self.push(other) 
    end 
end 

während += ist Syntax:

a += b 

und ist lediglich eine Abkürzung für das Schreiben:

a = a + b 

Also, um += Verhalten zu ändern, hat man die + Methode zu ändern:

class Array 
    def + other 
    # .... 
    end 
end 
Verwandte Themen