@I,@carolclarinet 有正确的想法,您可能不需要更多。但是,我想提一个更复杂的处理问题的方法,您可能会发现它在相关应用程序中很有用。首先,假设您的哈希看起来像这样:
h = {"bot" => ["a", "o"], "fred" => ["q", "o"], "mike" => ["o"], "larry" => ["h"]}
这就是你所拥有的,除了我已经制作了所有单个哈希值数组。显然,将它变成这种形式很简单。下面我将展示如何将值数组重新定义为我调用的新类的实例UserModes
,它是Array
. 通过这样做,您可以以非常自然的方式比较值数组:
h["bot"] # => ["a", "o"]
h["fred"] # => ["q", "o"]
h["bot"].can_kick? h["fred"] # => false
h["mike"] # => ["o"]
h["bot"].can_kick? h["mike"] # => true
h["larry"] # => ["h"]
h["bot"].can_kick? h["larry"] # => true
kickees[]
h.each {|k,v| kickees << k if k!="bot" && h["bot"].can_kick?(h[k])} # final () req'd
# kickees => ["mike", "larry"]
如果添加其他方法:
h["bot"] < h["fred"] # => true
h["bot"] >= h["fred"] # => false
h["bot"] == h["mike"] # => false
h["bot"] > h["mike"] # => true
h["bot"] <= h["larry"] # => false
h["bot"] >= h["larry"] # => true
这是类定义:
class UserModes < Array
# Change > to >= in in can_kick? if I've misunderstood the kicking rule
def can_kick?(other) rating(self) > rating(other) end
# Add any or all of the following if useful to you:
def <=>(other) rating(self) <=> rating(other) end
def ==(other) rating(self) == rating(other) end
def <(other) rating(self) < rating(other) end
def >(other) rating(self) > rating(other) end
def <=(other) rating(self) <= rating(other) end
def >=(other) rating(self) >= rating(other) end
private
def rating a
case
when (a.include? ?q) then 3
when (a.include? ?a) then 2
when (a.include? ?o) then 1
when (a.include? ?v) then 0
else
# raise exception
end
end
end
您会看到所有公共方法都使用私有方法rating
,它将数组转换为数字分数,与@carolclarinet 的答案一致。您可以将每个哈希值从一个实例转换Array
为一个实例,UserModes
如下所示:
h.each_key {|k| h[k] = UserModes.new(h[k])}
我们可以确认这按预期工作:
h["fred"].class => UserModes
您可以将这些值h
视为普通数组,但您现在还拥有该方法can_kick?
,如果需要,还可以使用其他几个方法。其中一些 ( < <= >= >
) 没有为Array
对象定义;必须定义others( <=> ==
) 以覆盖 中的同名方法Array
。