【问题标题】:Keeping the values of two variables from `each` method从“每个”方法中保留两个变量的值
【发布时间】:2016-09-11 17:27:36
【问题描述】:

我有以下代码:

session={"apple"=>["bp", "80APPM", "donald"]}
@like_list = session
@like_list.each do |key, value|
  value.each_with_index do |v, i|
    @like_list[key][i] = 2
  end
end
session    # => {"apple"=>[2, 2, 2]}
@like_list # => {"apple"=>[2, 2, 2]}

分配给变量session@like_list 的对象都已更改。有什么方法可以在不改变session的值的情况下执行上述代码?

我尝试使用 clonedup 但没有任何变化

【问题讨论】:

标签: ruby


【解决方案1】:

您需要复制原始哈希,以防止两个变量引用同一个对象。

@like_list = session.map { |key, value| [key, value.clone] }.to_h

【讨论】:

  • 此方法适用于单层散列,但如果有嵌套层,顶层以下的仍将被浅拷贝。要完成这项工作,您需要处理任意级别的嵌套。
  • @Michael,问题没有指定多级嵌套,session 的指定值只有一个,所以这个答案很好,比允许任意嵌套级别的方法更可取。
  • 我的评论只是为了警告任何试图在一般情况下使用它的人。问题和答案在 SO 上的生命周期很长。
【解决方案2】:

这行得通:

session={"apple"=>["bp", "80APPM", "donald"]}
@like_list = Marshal.load(Marshal.dump(session))
@like_list.each do |key, value|
  value.each_with_index do |v, i|
    @like_list[key][i] = 2
  end
end

它使用来自这个 SO 问题的Marshal.load(Marshal.dump(session)) 解决方案:Ruby dup/clone recursively

【讨论】:

  • Marshal.load(Marshal.dump(session)).each_with_object({}) { |(k,v),h| h[k] = [2]*v.size }@like_list = Marshal.load(Marshal.dump(session)).tap { |h| h.each { |k,v| h[k] = [2]*v.size } },但正如我在其他 cmets 中指出的那样,我认为这个问题不需要深入探讨。
【解决方案3】:

使用Hash.deep_dup

@like_list = session.deep_dup

Here is the documentation 用于方法。

编辑:

这个方法来自activesupport 库,它包含在 Rails 中。正如 cmets 中所建议的那样,这种方法曾经是有问题的,但是as of Rails 4,它的表现更符合预期。我测试了上面的例子,它适用于activesupport 4.2.3

如果你不使用Rails,你需要加载activesupport

require 'active_support'

【讨论】:

  • Hash#deep_dup 不适用于包含的数组。试试看。
  • @MichaelGaskill 您使用的是哪个 ruby​​ 版本?我正在运行 2.3.0,它可以工作
  • Ruby 2.2.5、2.1.9 和 1.9.3,它们都不起作用。它必须在新的中修复。这个错误已经存在了很多年......
  • 我正在使用 Ruby 2.3 和 Rails 4。 deep_dup 方法对我有用。两个变量值都被保留。谢谢!
  • 您已经回答了一个没有被问到的问题。在没有指定session["apple"] 可以有多层嵌套的情况下,并且给定值没有嵌套的事实,我们应该假设没有嵌套,在这种情况下加载activesupport(注意没有Rails 标签)是矫枉过正。很好地展示如何处理嵌套,但只是作为旁白。
猜你喜欢
  • 2015-02-23
  • 1970-01-01
  • 2011-10-07
  • 2021-02-11
  • 2014-12-22
  • 1970-01-01
  • 1970-01-01
  • 2021-06-26
  • 2016-08-04
相关资源
最近更新 更多