不将nil值分配给散列

时间:2011-11-29 22:49:28

标签: ruby-on-rails ruby hash ruby-1.9 null

当红宝石中的东西为零时,是否存在将事物分配给哈希的简写或最佳实践?例如,我的问题是我正在使用另一个哈希来构建它,如果其中的某些内容是nil,它会为该键分配nil,而不是仅仅将其保留。我理解为什么会这样,所以我的解决方案是:

hash1[:key] = hash2[:key] unless hash2[:key].nil?

因为我在key中实际指向nil的值中没有值。 (我宁愿有一个空哈希,而不是那个有{:key => nil}的哈希值,这不会发生)

我的问题是有更好的方法吗?我不想在作业结束时做一个delete_if。

7 个答案:

答案 0 :(得分:20)

如果你否定“除非”陈述

,请稍微缩短一点
hash1[:key] = hash2[:key] if hash2[:key]   # same as   if ! hash2[:key].nil?

您还可以在&&& Michael或Marc-Andre在其他答案中提出的陈述

这取决于你,你觉得最适合你的是什么。按照设计,Ruby总有多种方法来解决问题。

你也可以修改hash2:

hash1 = hash2.reject{|k,v| v.nil?}

hash2.reject!{|k,v| v.nil?}   # even shorter, if in-place editing of hash2

这将删除键/值对:key =>来自hash2的nil(如果你使用拒绝,就到位了)。

答案 1 :(得分:4)

我喜欢这个最好的,循环和条件覆盖所有在一行!

h1 = {:foo => 'foo', :bar => 'bar'}
h2 = {:foo => 'oof', :bar => nil}

h1.merge!(h2) { |key, old_val, new_val| new_val.nil? ? old_val : new_val }

#=> {:foo => 'oof', :bar => 'bar'}

这将用h2的值替换h1中的每个值,其中键是相同的,并且h2值不是nil。

答案 2 :(得分:3)

这样的事情怎么样?

hash2.each_pair do |key, value|
  next if value.nil?
  hash1[key] = value
end

如果你只做一个作业,这可能会刮掉几个字符:

hash2[:key] && hash1[:key] = hash2[:key]

我的第一个例子也可以进一步削减:

hash2.each_pair{ |k,v| v && hash1[k] = v }

我认为第一个是最容易阅读/理解的。此外,示例2和3将跳过评估false(nilfalse)的任何内容。最后一个示例是一行,不会跳过false值:

hash2.each_pair{ |k,v| v.nil? || hash1[k] = v }

答案 3 :(得分:3)

我不确定这是不是更好,但是

hash2[:key] && hash[:key] = hash2[:key]

可行。请注意,falsenil的行为方式相同,如果这不是您想要的

!hash2[:key].nil? && hash[:key] = hash2[:key]

会更好。所有这一切都假设:key是您可能无法控制的任意值。

答案 4 :(得分:3)

我认为最佳做法是将nil值复制到哈希值。如果通过选项:foo => nil,则可能意味着某些内容,并且应该覆盖:foo的默认42。这样也可以更容易地选择默认为true的选项,尽管在这些情况下应该使用fetch

opt = hash.fetch(:do_cool_treatment, true) # => will be true if key is not present

有很多方法可以复制值,包括nilfalse

对于单个密钥,您可以使用has_key?代替查找:

hash1[:key] = hash2[:key] if hash2.has_key? :key

对于所有(或多个)键,请使用merge!

hash1.merge!(hash2)

如果您只想对hash2的几个键执行此操作,则可以对其进行切片:

hash1.merge!(hash2.slice(:key, ...))

答案 5 :(得分:1)

好的,所以如果合并不起作用,因为你想要更多控制:

hash1[:key] = hash2.fetch(:key, hash1[:key])

这将设置hash1的:key为hash2,除非它不存在。在这种情况下,它将使用默认值(第二个参数来获取),这是hash1的键

答案 6 :(得分:0)

将此添加到初始值设定项 hash.rb

class Hash
  def set_safe(key,val)
    if val && key
      self[key] = val
    end
  end
end

使用

hash = {}
hash.set_safe 'key', value_or_nil