说我有哈希:
a = {b: "asdfgh", c: "qwerty", d: "dvorak"}
我希望能够判断出除了我指定的键之外是否还有其他键,如下所示:
a.has_other_keys?(:b, :c, :d)
=> false
a.has_other_keys?(:c, :d)
=> true
但如果没有指定的键,我不希望它返回false:
a.has_other_keys?(:b, :c, :d, :e)
=> true
在ruby中有一种简单的方法吗?
答案 0 :(得分:2)
Rails has an except/except! method返回删除了这些键的哈希值。如果您已经在使用Rails,则可以使用它
class Hash
# Returns a hash that includes everything but the given keys.
# hash = { a: true, b: false, c: nil}
# hash.except(:c) # => { a: true, b: false}
# hash # => { a: true, b: false, c: nil}
#
# This is useful for limiting a set of parameters to everything but a few known toggles:
# @person.update(params[:person].except(:admin))
def except(*keys)
dup.except!(*keys)
end
# Replaces the hash without the given keys.
# hash = { a: true, b: false, c: nil}
# hash.except!(:c) # => { a: true, b: false}
# hash # => { a: true, b: false }
def except!(*keys)
keys.each { |key| delete(key) }
self
end
end
使用上面你可以:
bundle :002 > a = {b: "asdfgh", c: "qwerty", d: "dvorak"}
=> {:b=>"asdfgh", :c=>"qwerty", :d=>"dvorak"}
bundle :006 > a.except(:b)
=> {:c=>"qwerty", :d=>"dvorak"}
bundle :007 > a.except(:b).length
=> 2
bundle :008 > a.except(:b, :c, :d, :e).length
=> 0
在纯Ruby中,您可以执行以下操作:
2.2.2 :010 > a.select{|x| ![:b, :c, :d, :e].include?(x)}
=> {}
2.2.2 :011 > a.select{|x| ![:b, :c, :d, :e].include?(x)}.length
=> 0
答案 1 :(得分:2)
def subset_of_keys?(h, other_keys)
(other_keys - h.keys).empty?
end
h = { b: "asdfgh", c: "qwerty", d: "dvorak"}
subset_of_keys? h, [:d, :b]
#=> true
subset_of_keys? h, [:b, :w, :d]
#=> false
请参阅Array#-。
答案 2 :(得分:2)
如果这不一定是高性能解决方案,您可以考虑使用Array算术(这是一个很好的Ruby功能)。
例如:
你的哈希:
a = {b: "asdfgh", c: "qwerty", d: "dvorak"}
我们已知的密钥:
known_keys = [:b, :c]
其余的键:
other_keys = a.keys - known_keys
other_keys.empty?
对于true
/ false
语句,我们可以执行以下操作:
(a.keys - [:b, :c]).empty?
答案 3 :(得分:1)
您可以检查由键构造的集合是否相同:
require 'set'
class Hash
def has_other_keys?(*keys)
Set.new(keys) != Set.new(self.keys)
end
end