5

例如:

options = { fight: true,
 use_item: false,
 run_away: false,
 save_game: false }

我想要一个布尔表达式,它的计算结果为trueiff only :fightis true,其余的是false(如上图所示)。

我可以一起破解这个,但我正在努力训练自己编写更优雅的 ruby​​。谢谢!

编辑:黑客是:

(options[:fight] == true && options.delete(:fight).values.all {|x| !x})

4

8 回答 8

9

假设所有值都是严格的布尔值,它很简单:

options == {fight: true, use_item: false, run_away: false, save_game: false}

请参阅 == 方法的文档

于 2013-05-22T19:05:54.670 回答
8

灵感来自 Vitaliy 的回答:

options[:flight] && options.values.one?
于 2013-05-22T19:24:51.303 回答
2

我认为你的 hack 还不错。不过可以稍微简化一下:

options.delete(:flight) && options.values.none?
于 2013-05-22T19:15:52.560 回答
1
options.find_all{|k,v| v } == [[:fight, true]]

或者

options.values.count(true) == 1 && options[:fight]
于 2013-05-22T18:58:40.890 回答
1

怎么样:

options.all? {|k,v| k == :fight ? v : !v}

对于更一般的方法:

def is_action?(options, action)
  options.all? {|k,v| k == action ? v : !v}
end

is_action? options, :fight
# => true
于 2013-05-22T19:17:22.463 回答
1

这与散列中的键/元素的数量无关。

options[:fight] && options.find_all{|arr| !arr[1]}.size == options.size-1

也只是一个提示,在 ruby​​ 中,你永远不需要写类似的东西:

options[:fight] == true
于 2013-05-22T19:17:33.597 回答
0
options.select{ |k, v| v } == [[:fight, true]]
于 2013-05-22T21:11:56.660 回答
0

如果您控制哈希的内容,并且它相对较小,我会在私有方法中使用这样的东西作为通用解决方案。

def exclusively_true?(hash, key)
  return false unless hash.delete(key) == true
  !hash.has_value? true
end

require 'test/unit'
class TestExclusive < Test::Unit::TestCase
  def setup
    @test_hash = {foo: true, bar: false, hoge: false}
  end
  def test_exclusive
    assert_equal(true, exclusively_true?(@test_hash, :foo))
  end
  def test_inexclusive
    @test_hash[:bar] = true
    assert_equal(false, exclusively_true?(@test_hash, :foo))
  end
end

require 'benchmark'

h = {foo: true}
999.times {|i| h["a#{i}"] = false}
Benchmark.bmbm(30) do |x|
  x.report('exclusively_true') do
    1000.times do
      exclusively_true?(h, :foo)
    end
  end
end

人为的基准测试:(OS X 10.8.3 / 3 GHz / 8 GB)

ruby -v: ruby 2.0.0p0 (2013-02-24 revision 39474) [x86_64-darwin12.3.0]
Rehearsal ------------------------------------------------------------------
exclusively_true                 0.000000   0.000000   0.000000 (  0.000412)
--------------------------------------------------------- total: 0.000000sec

                                     user     system      total        real
exclusively_true                 0.000000   0.000000   0.000000 (  0.000331)
于 2013-05-29T00:41:23.477 回答