在Ruby中将字符串转换为数组再转换为多维哈希表

4

我不知道标题是否正确,但问题很简单:

我有一个值和一个键。

密钥如下:

"one.two.three"

现在,我该如何设置这个哈希表:

params['one']['two']['three'] = value


这绝对是一个重复的问题;在网站上认真搜索,你会找到更多的答案。 - Phrogz
3
如果您能提供一个链接,那么您的评论将更加有用。 - Misha Moroshko
3个回答

1
你可以尝试使用这段代码:
keys = "one.two.three".split '.' # => ["one", "two", "three"]
params = {}; value = 1; i = 0;  # i is an index of processed keys array element
keys.reduce(params) { |hash, key|
    hash[key] = if (i += 1) == keys.length
      value # assign value to the last key in keys array
    else
      hash[key] || {} # initialize hash if it is not initialized yet (won't loose already initialized hashes)
    end
}
puts params # {"one"=>{"two"=>{"three"=>1}}}

看起来不错,本来希望能用一行代码解决,但这样也可以...谢谢! - Tim Baas
1
@Tim。不需要一行代码,只需创建一个抽象Hash#set_from_path(path, value),用良好、清晰、易于维护的代码编写。 - tokland

1

使用递归:

def make_hash(keys)
  keys.empty? ? 1 : { keys.shift => make_hash(keys) }
end

puts make_hash("one.two.three".split '.')
# => {"one"=>{"two"=>{"three"=>1}}}

这样创建一个新的哈希表是可以的,但我认为 OP 想要更新一个已存在的哈希表... - tokland

1
你可以使用inject方法:
key = "one.two.three"
value = 5

arr = key.split(".").reverse
arr[1..-1].inject({arr[0] => value}){ |memo, i| {i => memo} }
# => {"one"=>{"two"=>{"three"=>5}}}

那我可以这样把它变成一行代码吗:hash = key.split(".").reverse[1..-1].inject({arr[0] => value}){ |memo, i| {i => memo}} - Tim Baas
+Tim,你的一行代码中未定义arr - DNNX
1
"one.two.three".split('.').reverse.inject(5) { |x, y| { y => x } } 的输出结果为 => {"one"=>{"two"=>{"three"=>5}}} - DNNX
看起来很不错,但我如何在现有的哈希表上执行它? - Tim Baas
这太优雅了,应该被接受为答案! - BooVeMan

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接