2011-06-09 11 views
1

我有一組2個或多個對象,我想訂購。我一直這樣做:如何根據在數組屬性上使用<=>來訂購一組對象?

card.max_by{|strength| strength.score 

其中得分是一個整數得分我已經計算了一些任意的規則。我知道這是我會重構的東西,所以現在我正在這樣做。而「乾淨」的方式來給出分數手是給它值數組一樣

foo.score = [9,3,nil,4] 

,並將其與另一隻手可能有這樣

bar.score = [5,10,12,12] 

和Foo數組< => bar會告訴我,foo是更大的數組,所以它應該由max_by返回。問題是max_by顯然不會在數組上進行比較。有沒有另外一種方法可以做到這一點按數組值排序?

回答

1

如果這是你想要的(你真的想要的飛船運營商)只是基於陣列的排序,你想找到「最大」的排序,則:

Hand = Struct.new(:score) 

hands = [ 
Hand.new([9,3,0,4]), 
Hand.new([8,8,8,8]), 
Hand.new([5,10,12,12]), 
Hand.new([1,99,99,99]) 
] 

biggest = hands.sort_by(&:score).last 
p biggest 
#=> #<struct Hand score=[9, 3, 0, 4]> 

如果你真的只需要找到最大的手,不過,下面會比訂貨整個陣列更高效:

biggest = hands.inject do |max,hand| 
    if (max.score <=> hand.score) == -1 
    hand 
    else 
    max 
    end 
end 
p biggest 
#=> #<struct Hand score=[9, 3, 0, 4]> 

編輯:讀你的評論,如果你真的需要匹配的多個值,我這樣做:

Hand = Struct.new(:name,:score) do 
    MAX_SCORE_PART = 13 # 13 ranks in a suit 
    def numeric_score 
    value = 0 
    score.each_with_index do |part,i| 
     value += part.to_i * MAX_SCORE_PART**(score.length-i-1) 
    end 
    value 
    end 
end 

hands = [ 
    Hand.new('Bob', [9,3,nil,4]), 
    Hand.new('Jim', [8,8,8,8] ), 
    Hand.new('Foo', [5,10,12,12]), 
    Hand.new('Sam', [1,13,13,13]), 
    Hand.new('Zak', [9,3,0,4] ), 
] 

require 'pp' 
by_score = hands.group_by(&:numeric_score) 
pp by_score 
#=> {20284=> 
#=> [#<struct Hand name="Bob", score=[9, 3, nil, 4]>, 
#=> #<struct Hand name="Zak", score=[9, 3, 0, 4]>], 
#=> 19040=>[#<struct Hand name="Jim", score=[8, 8, 8, 8]>], 
#=> 12843=>[#<struct Hand name="Foo", score=[5, 10, 12, 12]>], 
#=> 4576=>[#<struct Hand name="Sam", score=[1, 13, 13, 13]>]} 

pp by_score[by_score.keys.max] 
#=> [#<struct Hand name="Bob", score=[9, 3, nil, 4]>, 
#=> #<struct Hand name="Zak", score=[9, 3, 0, 4]>] 

對於inject系實現:

def numeric_score 
    score.enum_for(:inject,0).with_index do |(val,part),i| 
    val += part.to_i * MAX_SCORE_PART**(score.length-i-1) 
    end 
end 
+0

對不起,「score」是數組,如同在數據庫查找中的sort_by一樣,如果數組1的第一個元素>數組2的第一個元素,第一個數組更大,如果第一個元素是捆綁的,然後你看下一個元素,等等。我認爲指定<=>會澄清,因爲在我看來,這是運營商的工作原理。我想要最大的「分數」,但是如果有5個物體和2個具有相同的最大分數,我需要它們兩個。我假設max_by是這樣工作的。 – 2011-06-09 15:38:21

+0

@JeremySmith我的歉意,第三次閱讀,並專注於'<=>'我想我明白了。看我的編輯。 – Phrogz 2011-06-09 15:39:05

+0

非常感謝,不用道歉給予你多少給這個網站! – 2011-06-09 15:44:33

2

max_by作品與陣列 「的屬性」 就好:

# Phrogz's example 
Hand = Struct.new(:score) 
hands = [ 
Hand.new([9,3,0,4]), 
Hand.new([8,8,8,8]), 
Hand.new([5,10,12,12]), 
Hand.new([1,99,99,99]) 
] 
# 
hands.max_by(&:score) # => #<struct Hand score=[9, 3, 0, 4]> 

然而,如果陣列可以包含尼爾斯或其他值不相互比較,<=>可能會返回零和max_by可能會失敗。

相關問題