문제

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

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

puts arr.inspect
puts arr2.inspect

produces:

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

Is there anyway to do a deep copy of an array of strings, other than using Marshal as i understand that is a hack.

I could do:

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

but it doesn't seem very elegant, or efficient.

Thanks

도움이 되었습니까?

해결책

Your second solution can be shortened to arr2 = arr.map do |e| e.dup end (unless you actually need the behaviour of clone, it's recommended to use dup instead).

Other than that your two solutions are basically the standard solutions to perform a deep copy (though the second version is only one-level deep (i.e. if you use it on an array of arrays of strings, you can still mutate the strings)). There isn't really a nicer way.

Edit: Here's a recursive deep_dup method that works with arbitrarily nested 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

You might also want to define deep_dup for other containers (like Hash), otherwise you'll still get a shallow copy for those.

다른 팁

I recommend your initial idea, but written slightly more concisely:

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

I am in a similar situation and very concerned about speed. The fastest way for me was to make use of map{&:clone}

So try this:

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

세션 데이터가 데이터베이스에 저장된 경우 세션 쿠키가 암호화되어 세션의 데이터를 사용하여 매우 안전합니다.

세션 쿠키는 세션 ID, 사용자 에이전트 및 IP 주소 만 유지합니다.또한 세션은 5 분마다 만료되므로 (기본적으로 기본적으로) 세션을 하이킹하려면 누군가 쿠키 암호화를 끊을 필요가있는 세션을 하이킹하려면 IP 및 사용자 에이전트를 쿠키에 저장된 것으로 설정하고 5 에서이 모든 것을 수행하십시오.세션 ID가 변경되기 전에 분 창이 변경됩니다.

이것은 (내 의견으로) 매우 가능성이 없습니다.

구성 파일의 CSRF (Cross Site Request Forgery) 옵션을 사용하여 양식 보안을 늘리지 않으려면 (적절한 사용자 데이터 유효성 검사를 대체하는 것은 아무 것도 없음)

It looks so simple.. Just run the below code:

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

b[1] = 5

puts a
puts b

Run above code and you will notice the difference. Cheers !

You can use this hack:

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

But it is just for fun :)

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

And it will work only for 1 level arrays

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top