例如:
options = { fight: true,
use_item: false,
run_away: false,
save_game: false }
我想要一个布尔表达式,其评估结果为true
iff仅:fight
为true
,其余为false
(如上图所示)。
我可以一起破解这个,但我正在努力训练自己写出更优雅的红宝石。谢谢!
编辑:黑客正在:
(options[:fight] == true && options.delete(:fight).values.all {|x| !x})
答案 0 :(得分:9)
假设所有值都是严格的布尔值,它就像:
一样简单options == {fight: true, use_item: false, run_away: false, save_game: false}
答案 1 :(得分:8)
受Vitaliy的回答启发:
options[:flight] && options.values.one?
答案 2 :(得分:2)
我认为你的黑客并不坏。它可以简化一点:
options.delete(:flight) && options.values.none?
答案 3 :(得分:1)
options.find_all{|k,v| v } == [[:fight, true]]
或
options.values.count(true) == 1 && options[:fight]
答案 4 :(得分: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
答案 5 :(得分:1)
这个与散列中的键/元素数无关。
options[:fight] && options.find_all{|arr| !arr[1]}.size == options.size-1
同样只是一个提示,在红宝石中,你永远不需要写下这样的东西:
options[:fight] == true
答案 6 :(得分:0)
options.select{ |k, v| v } == [[:fight, true]]
答案 7 :(得分: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)