2016-04-26 24 views
0

Ich versuche, eine boolean Methode zu schreiben, wenn eine Summe von ganzen Zahlen in einem Array überprüft gleich 21. Hier ist der Code:Boolesche Methode ‚Blackjack‘ für Arrays

def twenty_one? (*arr) 
    arr.inject(0){|sum,x| sum + x } 
    arr.eql? (21) 
end 

Aber wenn ich überprüfe

puts twenty_one?(19, 2) 

es gibt false zurück, obwohl ich einige andere auch versuchte. Was fehlt mir in diesem Code?

Antwort

6

Enumrable#inject transformiert Array nicht zu Nummer. Sie überprüfen die Gleichheit von Array und Nummer, die immer false zurückgibt. Nach Ihrer Logik, sollten Sie das Ergebnis der inject mit der Nummer vergleichen:

def twenty_one? (*arr) 
    sum = arr.inject(0) { |sum,x| sum + x } 
    sum.eql?(21) 
end 

twenty_one?(19, 2) 
#=> true 

Oder Sie reduce verwenden können:

def twenty_one?(*arr) 
    arr.reduce(:+) == 21 
end 

Oder man kann es kürzer machen von Active mit Enumerable#sum:

def twenty_one?(*arr) 
    arr.sum == 21 
end 
+0

es Ihnen danken! das funktioniert. – annabretsko

+0

Die Verwendung von 'eql?' Ist wirklich ungewöhnlich. Normalerweise wird '==' erwartet. – tadman

+0

['Enumerable # sum'] (http://api.rubyonrails.org/classes/Enumerable.html#method-i-sum) ist eine Rails/ActiveSupport-Methode. – Stefan

4

Sie injizieren Summe, die die Summe am Ende des Arrays halten wird, aber der Bereich ist einmal aus dem Codeblock verloren, müssen Sie dies zu a zuweisen Variable wie Ilya zeigt oder verwenden Sie diese kürzere Version, die dieses Ergebnis zu 21 sofort vergleicht.

def twenty_one? (*arr) 
    arr.inject(:+) == 21 
end 

Siehe this Blog für eine detaillierte Erklärung von inject und der shothand: +

+0

das sieht kurz und ordentlich aus. Danke! – annabretsko

+0

Sie sind der erste, der antwortet, dass 'inject' das erste Element im Array als Seed verwendet, wenn kein Argument angegeben wird, das ist viel sauberer. – tadman

+1

@tadman, wenn das Array leer ist, gibt es nur falsche – peter