2013-05-07 15 views
6

私は配列で周りのビットを再生し、トラブル次のコードを理解する上で自分自身を発見されている:<<と+ =の違いは何ですか?

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 

これで何が起こりましたか?

second_array += third_array    # I have no clue 

すべての配列が同じではないのはなぜですか?

答えて

7

これらは、かなり異なる挙動を示す。 1つは新規のオブジェクトを作成して割り当て、もう1つは既存のオブジェクトを変更します。

+=は、second_array = second_array + third_arrayと同じです。これにより、third_arrayを引数としてsecond_arrayオブジェクトにメッセージ+が送信されます。

ドキュメントごとにArray.+は、2つの配列を連結して作成された新しい配列オブジェクトを返します。これにより、新しいオブジェクトが返されます。

Array.<<は、単に既存の配列オブジェクトの末尾にパラメータをプッシュ:

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 

パラメータが追加されている方法に違いがあります。

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] 

Array.+がプッシュするのではなく、連結を使用していますので、これは次のとおりです。他の要素を追加することで、それはあなたの配列が同じでない理由を知るのに役立ちます。既存のオブジェクトを変更するArray.concatとは異なり、Array.+は新しいオブジェクトを返します。あなたが好きなRubyの実装と考えることができ

:あなたの具体的な例では

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

は、あなたのオブジェクトは、最後に次のようになります。

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

だからあなたのポイント:

a = a + b 

ので、+=動作を変更するためには、1が+方法を変更することがあります。

a += b 

とは、単に書き込みの省略形ですたとえ2つの配列の内容が同じであっても、second_arrayに対して、新しい配列が作成され、それがthird_arrayと等しくないということですか? – nzs

+0

その@codedadはまだ答えられていません!誰もがこれを理解していますか? – rubybrah

+0

second_arrayはthird_arrayと等しくなりますが(新しいオブジェクトを作成した)、元の例でこれを示しています。 first_arrayはいずれも –

3

<<が配列にアイテムを追加し

+=は配列に配列を追加します。

例:

[1,2] << 3#戻り[1,2,3]

[1,2] += [3,4]#戻り[1,2,3,4]

+6

'[1,2] << [3,4]が' [1,2、[3,4]] 'IMHOを生成していることを示していれば、' << 'のあなたの例は良いでしょう。 – squiguy

+0

@ squiuyあなたが正しいです。私の例では、first_array = [1,2,3,4,5,6,7,8,9]とsecond_array = [[1,2,3,4,5,6,7、 8,9]]?これは正しいです? – rubybrah

+1

@rubybrah no。 '' first_array''は '' [1..9]] ''であり、 'second_array''は' [[1..9]] ' –

3

<<間にこれまでに言及されていない最後の差と+=一方

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

である:+=<<が方法であること、です構文:

class Array 
    def + other 
    # .... 
    end 
end 
関連する問題