質問

arr = ["red","green","yellow"]

arr2 = arr.clone
arr2[0].replace("blue")

puts arr.inspect
puts arr2.inspect

生成します:

["blue", "green", "yellow"]
["blue", "green", "yellow"]

私はハックであることを理解として元帥を使用するよりも、他の文字列の配列の深いコピーを行うには、とにかくあります。

私が行うことができます:

arr2 = []
arr.each do |e|
  arr2 << e.clone
end

しかし、それは非常にエレガントな、あるいは効率的ないないようです。

おかげ

役に立ちましたか?

解決

あなたの第二の溶液は、(あなたが実際にarr2 = arr.map do |e| e.dup endの行動を必要としない限り、それは代わりに使用cloneすることをお勧めします)dupに短縮することができます。

第二版は、あなたが文字列の配列の配列にそれを使用する場合、あなたはまだ文字列を変異させることができる唯一のレベルの深さ(すなわちですが、あなたの2つのソリューションは、(基本的には深いコピーを実行するための標準的なソリューションであることを以外は

))。よりよい道が本当にありません。

編集:ここでは任意にネストされた配列で動作する再帰的deep_dup方法があります:

class Array
  def deep_dup
    map {|x| x.deep_dup}
  end
end

class Object
  def deep_dup
    dup
  end
end

class Numeric
  # We need this because number.dup throws an exception
  # We also need the same definition for Symbol, TrueClass and FalseClass
  def deep_dup
    self
  end
end

また、(ハッシュのような)他のコンテナにdeep_dup定義したいかもしれませんそれ以外の場合は、あなたがまだそれらのための浅いコピーを取得します。

他のヒント

私はあなたの最初のアイデアをお勧めしますが、もう少し簡潔に書かれます:

arr = ["red","green","yellow"]
arr2 = arr.inject([]) { |a,element| a << element.dup }

私は似たような状況にいると非常にスピードを懸念します。私のための最速の方法だったmap{&:clone}を利用するために、

だから、これを試してみます:

pry(main)> a = (10000..1000000).to_a.shuffle.map(&:to_s)
pry(main)> Benchmark.ms { b = a.deep_dup }                                                                                     
=> 660.7760030310601
pry(main)> Benchmark.ms { b = a.join("--!--").split("--!--") }
=> 605.0828141160309
pry(main)> Benchmark.ms { b = a.map(&:clone) }
=> 450.8283680770546

あなたがコードに従うことによって、配列aの深いコピーを作成することができます:

 Marshal.load(Marshal.dump(a))

..ただ、以下のコードを実行し、簡単なので、

に見えます

a = [1,2,3]
b = [].replace(a)

b[1] = 5

puts a
puts b

上記のコードを実行して、あなたは違いに気づくでしょう。乾杯!

あなたはこのハックを使用することができます

arr1 = %w{ red green blue }
arr2 = arr1.join("--!--").split("--!--")

しかし、それはちょうど楽しみのためです:)

arr2[0].replace("lol")
p arr1
#=> ["red", "green", "blue"]
p arr2
#=> ["lol", "green", "blue"]
そして、それは1つのレベルのアレイにのみ動作します。

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top