Ruby挖掘集-使用Hash#dig分配值

时间:2019-06-17 15:57:37

标签: ruby

基本上我想使用#dig分配一个数组。

我必须这样:

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

我会使用Hash#dig

hash.dig(:first, :second) = [1,2,3,4]

如何分配此值?

3 个答案:

答案 0 :(得分:3)

dig不能用于将值分配给哈希,此方法仅用于访问值。

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

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

或:

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

您也可以在该帖子中使用该方法:How to set dynamically value of nested key in Ruby hash

他们创建了一个新的哈希方法,以将嵌套值动态分配给哈希。

答案 1 :(得分:3)

您可以创建行为类似于所需的哈希值。 Hash.new包含一个块,只要键查找失败,该块就会被调用。发生这种情况时,我们可以创建一个空哈希:

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]}}

请注意,尽管仅访问不存在的密钥将导致创建新的哈希:

hash.dig(:a, :b, :c) # => {}

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

hash[:foo].nil? # => false

答案 2 :(得分:2)

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

一个人可以使用Enumerable#reduce(又称inject):

def undig(*keys, value)
  keys[0..-2].reverse_each.reduce (keys.last=>value) { |h,key| { key=>h } }   
end

undig(:first, :second, [1,2,3,4])
  #=> {:first=>{:second=>[1, 2, 3, 4]}} 

或递归:

def undig(*keys, value)
  keys.empty? ? value : { keys.first=>undig(*keys.drop(1), value) }
end

undig(:first, :second, [1,2,3,4])
  #=> {:first=>{:second=>[1, 2, 3, 4]}}