【问题标题】:Set hash value at arbitrary location在任意位置设置哈希值
【发布时间】:2013-04-01 22:17:16
【问题描述】:

我正在开发一个应用程序,我想修改现有哈希的一部分,如下所示:

{a: {b: {c: 23}}}

成为:

{a: {b: {c: [23]}}}

但是,要设置的确切密钥是动态的,并且在散列中处于未知深度。有没有办法在给定键数组的哈希中设置一个值?我希望是这样的:

my_hash['a','b','c'] = new_value

通过递归从任意深度获取值很简单,但由于遍历适用于数据的副本,而不是引用,因此我不知道如何设置值而不在遍历期间重建整个数组。

【问题讨论】:

  • 问题:1) 递归/遍历是否出于任何原因必须处理数据副本? 2)在代码中,当您遍历副本时,您是否有对原始数据结构的引用(例如,它是否存储在范围内的变量中)?
  • 1) 它不必在副本上工作。 2) 对原始结构的引用可用最终目标是为我的应用程序修补 Hash,以便我可以调用 my_hash['a','b','c'] 或 my_hash.set_value_at['a',' b','c'].
  • 你不能那样做。输入和预期输出均无效。
  • {a: {b: {c: {23}}}} 语法不正确
  • 抱歉,问题语法已更正。

标签: ruby


【解决方案1】:

除了语法(my_hash['a','b','c']),以下将做你想做的事

h = {a: {b: {c: { e: 23}}, d: 34}}
keys = ['a','b','c']

def replace_nested_value_by(h, keys, value)
  if keys.size > 1
    replace_nested_value_by(h[keys.first.to_sym], keys[1..-1], value)
  elsif keys.size == 1
    h[keys.first.to_sym] = value
  end
end

puts h
replace_nested_value_by(h, keys, 42)
puts h

【讨论】:

  • 以前没见过crawl,我在irb 中也看不到——它来自哪里?
  • 回答的时候改了函数名,调用的时候忘记改了。看我以前的编辑,现在是正确的。
  • @toch OP 给出的 {a: {b: {c: {23}}}} 与您的哈希 {a: {b: {c: 23}}} 完全不同。你是怎么使用它的?
  • 那是我的错。编辑后的原始问题有效。
  • @iAmRubuuu {a: {b: {c: {23}}}} 不正确,我说这是一个错字,@superlou 的意思是 {a: {b: {c: 23}}}
【解决方案2】:

作为对 toch 答案的补充,只是有点超出评论范围,我还建议这可能是使用 inject 的好地方:

def nested_replace(hash, *keys, last_key, value)
  result = keys.inject(hash) { |r, k| r[k] }
  result[last_key] = value
end

h = {a: {b: {c: [23]}}}
nested_replace h, :a, :b, :c, 42
puts h
# => {:a=>{:b=>{:c=>42}}}

就个人而言,如果在查看递归之前有一种自然的方式来表达事物,我倾向于使用 Ruby 的枚举器。

【讨论】:

  • 我也喜欢枚举,并且可以通过 nested_replace(h, *[:a, :b, :c], 42) 将哈希位置作为数组传递(起初对我来说并不明显,所以发布以防其他人来看)。
猜你喜欢
  • 1970-01-01
  • 2013-09-19
  • 2016-07-19
  • 2021-02-05
  • 2021-02-20
  • 1970-01-01
  • 2011-10-30
  • 1970-01-01
  • 2017-09-02
相关资源
最近更新 更多