首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Ruby dig set -使用Hash#dig赋值

Ruby dig set -使用Hash#dig赋值
EN

Stack Overflow用户
提问于 2019-06-17 23:57:38
回答 3查看 2.4K关注 0票数 6

基本上,我想使用#dig赋值一个数组。

我的has必须是这样的:

代码语言:javascript
复制
hash = {
   :first => {
      :second => [1,2,3,4]
  }
}

我会使用Hash#dig

代码语言:javascript
复制
hash.dig(:first, :second) = [1,2,3,4]

如何分配此值?

EN

回答 3

Stack Overflow用户

发布于 2019-06-18 00:09:26

您可以创建一个行为像您想要的那样的散列。Hash.new接受一个块,每当键查找失败时都会调用该块。当发生这种情况时,我们可以创建一个空的散列:

代码语言:javascript
复制
hash = Hash.new { |hash, key| hash[key] = Hash.new(&hash.default_proc) }

hash[:first][:second] = [1, 2, 3, 4]

hash # => {:first=>{:second=>[1, 2, 3, 4]}}

但请注意,仅访问不存在的键将导致创建新的散列:

代码语言:javascript
复制
hash.dig(:a, :b, :c) # => {}

hash # => {:first=>{:second=>[1, 2, 3, 4]}, :a=>{:b=>{:c=>{}}}}

hash[:foo].nil? # => false
票数 6
EN

Stack Overflow用户

发布于 2019-06-18 01:19:31

我假设我在对问题的评论中提出的问题的答案是“是”。

可以使用Enumerable#reduce (也称为inject):

代码语言:javascript
复制
def undig(*keys, value)
  keys[0..-2].reverse_each.reduce (keys.last=>value) { |h,key| { key=>h } }   
end

代码语言:javascript
复制
undig(:first, :second, [1,2,3,4])
  #=> {:first=>{:second=>[1, 2, 3, 4]}} 

或递归:

代码语言:javascript
复制
def undig(*keys, value)
  keys.empty? ? value : { keys.first=>undig(*keys.drop(1), value) }
end

代码语言:javascript
复制
undig(:first, :second, [1,2,3,4])
  #=> {:first=>{:second=>[1, 2, 3, 4]}} 
票数 4
EN

Stack Overflow用户

发布于 2019-06-18 00:02:51

dig不能用于为Hash赋值,此方法仅用于访问值。

对于您的情况,您可以同时执行以下两种操作之一:

代码语言:javascript
复制
hash = { first: { second: [1, 2, 3, 4] } }

或者:

代码语言:javascript
复制
hash[:first] = { second: [1, 2, 3, 4] }

你也可以使用这篇文章中的方法:How to set dynamically value of nested key in Ruby hash

它们创建了一个新的散列方法来动态地将嵌套的值分配给散列。

票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/56634950

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档