Frage

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

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

puts arr.inspect
puts arr2.inspect

erzeugt:

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

Gibt es trotzdem eine tiefe Kopie eines Arrays von Strings zu tun, andere als die Verwendung von Marschall, wie ich verstehen, dass ein Hack.

ich tun konnte:

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

aber nicht sehr elegant erscheinen, oder effizient.

Danke

War es hilfreich?

Lösung

Ihre zweite Lösung kann auf arr2 = arr.map do |e| e.dup end verkürzt werden (es sei denn, Sie tatsächlich das Verhalten von clone brauchen, es zu benutzen dup empfohlen wird statt).

Anders als das Ihre beiden Lösungen sind im Grunde die Standardlösungen eine tiefe Kopie auszuführen (wenn auch die zweite Version nur eine Ebene tief ist (dh, wenn Sie es auf einem Array von Arrays von Strings verwenden, können Sie immer noch die Saiten mutieren )). Es ist nicht wirklich ein schöner Weg.

Edit: Hier ist eine rekursive deep_dup Methode, dass die Arbeiten mit beliebig verschachtelt Arrays:

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

Sie möchten vielleicht auch für andere Behälter definieren deep_dup (wie Hash), sonst werden Sie noch eine flache Kopie für diejenigen erhalten.

Andere Tipps

ich Ihre Idee empfehlen, aber etwas prägnanter geschrieben:

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

Ich bin in einer ähnlichen Situation und sehr besorgt über die Geschwindigkeit. Der schnellste Weg für mich war zu Verwendung von map{&:clone} machen

So versuchen Sie dies:

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

Sie können von folgendem Code eine tiefe Kopie des Arrays a machen:

 Marshal.load(Marshal.dump(a))

Es sieht so einfach .. Nur die folgenden Code ausführen:

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

b[1] = 5

puts a
puts b

Ausführen obigen Code, und Sie werden den Unterschied bemerken. Cheers!

Sie können diesen Hack verwenden:

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

Aber es ist nur zum Spaß:)

arr2[0].replace("lol")
p arr1
#=> ["red", "green", "blue"]
p arr2
#=> ["lol", "green", "blue"]

Und es wird nur für 1 Level-Arrays arbeiten

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top