It looks like you're trying to see if there are any two numbers in the array that add up to the specified value x
. However, your code just picks two numbers at random and checks if those numbers add up.
Ruby has the Array#combination
method, which generates all combinations of a given length:
def contains_pair_for_sum?(arr, n)
!!arr.uniq.combination(2).detect { |a, b| a + b == n }
end
A few things to note:
First, we named it according to Ruby conventions: each word is
separated_by_underscores
. The?
on the end means that the method is a predicate method and returns a true or false value.Inside the method, a few things happen. Let's look at that line, piece by piece.
arr
: We take the array that was passed in.<...>.uniq
: We only look at the unique elements (because the OP wants to pick two different numbers).<...>.combination(2)
: We ask for all combinations from the array of length 2. If the array was[4, 5, 6]
, we'd get[[4, 5], [4, 6], [5, 6]]
.<...>.detect { |a, b| a + b == n }
: We look for the first combination that adds up ton
. If we found one, that's the result of that method. Otherwise, we getnil
.!!<...>
: Finally, we take the result we got fromdetect
and negate it twice. The first negation produces a Boolean value (true
if the value we got wasnil
, orfalse
if it's anything else); the second negation produces a Boolean value that's identical to the truth value of the first negation. This is a Ruby idiom to coerce a result into being eithertrue
orfalse
.
Let's see it in action:
array = [4, 5, 9, 7, 8]
contains_pair_for_sum?(array, 11)
# => true (because [4, 7] sums to 11)
contains_pair_for_sum?(array, 17)
# => true (because [9, 8] sums to 17)
contains_pair_for_sum?(array, 100)
# => false (no pair matched)