以条件方式构建哈希

Bac*_*cko 38 ruby hash conditional

我正在使用Ruby on Rails 3.0.10,我想以条件方式构建一个哈希键\值对.也就是说,如果条件匹配,我想添加一个键及其相关值:

hash = {
  :key1 => value1,
  :key2 => value2, # This key2\value2 pair should be added only 'if condition' is 'true'
  :key3 => value3,
  ...
}
Run Code Online (Sandbox Code Playgroud)

我怎么能这样做并保持代码的"良好"可读性?我"被迫"使用这种merge方法吗?

Rus*_*ell 55

我更喜欢tap,因为我认为它提供了比这里描述的更清晰的解决方案,不需要任何hacky删除元素,并清楚地定义哈希的构建范围.

这也意味着你不需要声明一个我总是讨厌的不必要的局部变量.

如果您之前没有遇到它,那么tap非常简单 - 它是一个Object接受块的方法,并始终返回它被调用的对象.因此,要有条件地构建哈希,您可以这样做:

Hash.new.tap do |my_hash|
  my_hash[:x] = 1 if condition_1
  my_hash[:y] = 2 if condition_2
  ...
end
Run Code Online (Sandbox Code Playgroud)

有许多有趣的用途tap,这只是一个.

  • 这取决于您是否要将其分配给任何东西.对我来说,通常情况下,这对于一个方法来说就足够了,所以这只是方法的整个主体 - 不需要将它分配给任何东西. (4认同)
  • 作业不见了?`hash = Hash.new.tap do ...` (2认同)

tok*_*and 26

功能方法:

hash = {
  :key1 => 1,
  :key2 => (2 if condition),
  :key3 => 3,
}.compact 
Run Code Online (Sandbox Code Playgroud)

注意:对于Ruby <2.4.0或不使用active-support,请替换.compact.reject { |k, v| v.nil? }.

  • 这种方法的缺点是如果您需要哈希中的某些值为零 (2认同)
  • 如果您不使用Ruby 2.4+并使用Rails,ActiveSupport还提供`Hash#compact`. (2认同)

dwh*_*len 9

如果您担心可读性,可能最好保持简单:

hash = {}
hash[:key1] = value1
hash[:key2] = value2 if condition?
hash[:key3] = value3
...
Run Code Online (Sandbox Code Playgroud)


Mla*_*vić 6

把事情简单化:

hash = {
  key1: value1,
  key3: value3,
}

hash[:key2] = value2 if condition
Run Code Online (Sandbox Code Playgroud)

通过这种方式,您还可以在视觉上分离您的特殊情况,如果它隐藏在哈希文字赋值中,则可能会被忽视。