【问题标题】:Ruby dig set - Assign values using Hash#digRuby dig set - 使用 Hash#dig 分配值
【发布时间】:2019-10-31 06:17:33
【问题描述】:

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

我必须是这样的:

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

我会使用Hash#dig

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

如何分配这个值?

【问题讨论】:

  • 您的意思是,“给定:first:second[1,2,3,4],我如何创建一个哈希{ :first=>{:second=>[1,2,3,4] } }”?如果是这样,那与dig无关。
  • 如果你错过了,我问你一个问题。

标签: ruby


【解决方案1】:

您可以创建一个行为与您想要的一样的哈希。 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

【讨论】:

  • Hash.new { |h,k| h[k] = Hash.new(&h.default_proc) } 让您可以无限地定义嵌套键,而不仅仅是在前 2 级
  • 将默认过程附加到散列具有必须识别的后果。例如,不能执行hash[:cat].nil? 来确定哈希是否有一个键:cat,为hash[:cat] #=> {}。 (当然可以使用hash.key?(:cat) #=> false,无论如何这是一种很好的做法。)。另一个例子是hash[:fisrt][:second] == [1,2,3,4] #=> false,掩盖了我拼错:first的事实。如果没有默认 proc,则会引发异常。我的偏好是避免在构造哈希后使用默认 proc,但当然不能简单地删除它。
  • 感谢您的意见,伙计们。我已经相应地编辑了我的答案。
【解决方案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]}} 

【讨论】:

  • 这是以Hash#bury .. bugs.ruby-lang.org/issues/11747 的形式向ruby core 提出并被拒绝的
  • 另外,如果您的 undig 方法可以在现有哈希上调用,那可能会很好
  • dig 不仅限于哈希,它还可以从数组(或混合哈希数组结构)中检索值。 undig 应该也可以工作。
  • @Stefan,看我的第一句话。如果让 OP 回答我的问题,我们会知道更多。也许undig 是我方法名称的糟糕选择。顺便说一句,你忘了OpenStruct#dig
【解决方案3】:

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

对于你的情况,你可以做两件事之一:

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

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

【讨论】:

    猜你喜欢
    • 2016-03-24
    • 2016-04-09
    • 1970-01-01
    • 1970-01-01
    • 2016-04-09
    • 1970-01-01
    • 2021-04-09
    • 2011-07-11
    • 2017-02-08
    相关资源
    最近更新 更多