ruby散列中的条件键/值

luc*_*nte 52 ruby

是否有一个很好的(一行)方式在ruby中编写一个哈希值,只有条件满足时才有一些条目?我想到了

{:a => 'a', :b => ('b' if condition)}
Run Code Online (Sandbox Code Playgroud)

但是,:b == nil如果条件没有得到满足,那就离开了.我意识到这可以在两行左右轻松完成,但在一行中会更好(例如将哈希传递给函数时).

我错过了(还)另一个红宝石的惊人功能吗?;)

Rus*_*ell 52

从Ruby 1.9+开始,如果你想根据你可以使用的条件构建一个哈希tap,这是我最喜欢的东西.这会将它分成多行,但更具可读性恕我直言:

{}.tap do |my_hash| 
  my_hash[:a] = 'a'
  my_hash[:b] = 'b' if condition
end
Run Code Online (Sandbox Code Playgroud)


Thi*_*ilo 51

您可以首先使用key => nil创建散列,以便在不满足条件时使用,然后删除值为nil的那些对.例如:

{ :a => 'a', :b => ('b' if cond) }.delete_if{ |k,v| v.nil? }
Run Code Online (Sandbox Code Playgroud)

收益率,对于cond == true:

{:b=>"b", :a=>"a"}
Run Code Online (Sandbox Code Playgroud)

并为cond == false

{:a=>"a"} 
Run Code Online (Sandbox Code Playgroud)

UPDATE

这是相同的 - 更简洁,并在ruby 1.9.3表示法:

{ a: 'a', b: ('b' if cond) }.reject{ |k,v| v.nil? }
Run Code Online (Sandbox Code Playgroud)

更新Ruby 2.4+

从ruby 2.4.0开始,你可以使用紧凑的方法:

{ a: 'a', b: ('b' if cond) }.compact
Run Code Online (Sandbox Code Playgroud)

  • 但是你可以说它不是一个单行.当然不是我愿意的.:) (3认同)
  • @Gripp:这不是真的。请参阅:``ruby [1] pry(main)> {a: 1}.compact => {:a=>1} ```。不过,对于“紧凑!”来说确实如此。 (3认同)
  • 您可以将`(cond?'b':nil)`缩短为`('b'if cond)`。有趣的主意。 (2认同)

Mic*_*ley 25

有兴趣看到其他答案,但这是我能想到的最好的单线程(我在单线上也是出了名的坏:P)

{:a => 'a'}.merge( condition ? {:b => 'b'} : {} )
Run Code Online (Sandbox Code Playgroud)

  • 嗯,好主意,但是有多个条件输入可能会变得非常难看...... (2认同)
  • 我认为这比接受的答案要好,因为它不会干扰任何故意为零的哈希值。 (2认同)

jua*_*tas 21

> = Ruby 2.4:

{a: 'asd', b: nil}.compact
=> {:a=>"asd"}
Run Code Online (Sandbox Code Playgroud)


Pau*_*rth 8

在 Ruby 2.0 中,有一个**用于哈希(和关键字参数)的双 splat 运算符 ( ),类似于*用于数组(和位置参数)的旧 splat 运算符 ( )。所以你可以说:

{a: 'b', **(condition ? {b: 'b'} : {})}
Run Code Online (Sandbox Code Playgroud)


Den*_*nis 8

这里有很多聪明的解决方案,但IMO最简单,也是最好的方法

hash = { a: 'a', b: 'b' }
hash[:c] = 'c' if condition
Run Code Online (Sandbox Code Playgroud)

它违背了OP的要求,即两行,但其他答案似乎只是单行.让我们面对现实,这是最简单的解决方案,它很容易阅读.