Question

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

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

puts arr.inspect
puts arr2.inspect

produit:

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

Y at-il de toute façon à faire une copie complète d'un tableau de chaînes, autre que d'utiliser le maréchal que je comprends est un hack.

Je pourrais faire:

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

mais il ne semble pas très élégant, ni efficace.

Merci

Était-ce utile?

La solution

Votre deuxième solution peut être raccourci à arr2 = arr.map do |e| e.dup end (sauf si vous avez réellement besoin le comportement de clone, il est recommandé d'utiliser dup à la place).

Autre que vos deux solutions sont essentiellement les solutions standard pour effectuer une copie complète (bien que la deuxième version est seulement un niveau profond (si vous l'utilisez sur un tableau de tableaux de chaînes, vous pouvez toujours muter les cordes )). Il n'y a pas vraiment une façon plus agréable.

Edit: Voici une méthode deep_dup récursif qui fonctionne avec des tableaux imbriqués de façon arbitraire:

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

Vous pouvez également définir deep_dup pour d'autres conteneurs (comme Hash), sinon vous aurez toujours une copie peu profonde pour ceux-ci.

Autres conseils

Je recommande votre idée initiale, mais un peu plus écrit de manière concise:

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

Je suis dans une situation similaire et très préoccupé par la vitesse. La façon la plus rapide pour moi était d'utiliser map{&:clone}

Donc, essayez ceci:

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

Vous pouvez faire une copie en profondeur de a tableau par le code suivant:

 Marshal.load(Marshal.dump(a))

Il semble si simple .. Il suffit d'exécuter le code ci-dessous:

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

b[1] = 5

puts a
puts b

Exécuter code ci-dessus et vous remarquerez la différence. Vive!

Vous pouvez utiliser ce hack:

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

Mais il est juste pour le plaisir:)

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

Et il ne fonctionnera que pour 1 tableaux de niveau

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top