.find
method utilizes a callback function to iterate over each item in an array until a match is found. The first argument passed to the callback is the current item being iterated over. If the callback returns a truthy value for any element, then the .find
method will return that specific item.
During the initial iteration where i = 0
and values[i]
equals to 11
, the calculation
(sum) => { return k-values[i] === sum}
will first check if
17 - 11 === 11
, followed by
17 - 11 === 15
, and then
17 - 11 = 3
, and so on.
This condition typically checks if two numbers in the given array add up to the defined k
, however, there are bugs present. For instance, an array with only one element like [1]
will compare 1 against itself during the first iteration, resulting in a sum of 2:
function problemOne_Solve() {
const k = 2;
const values = [1];
for (i=0; i < values.length; i++) {
if ( values.find( (sum) => { return k-values[i] === sum} ) ) return true;
}
return false;
}
console.log(problemOne_Solve());
This approach is incorrect. Furthermore, when using the .find
method, it may return a found value, which could be 0 when dealing with number arrays, leading to a falsey result. As a result, even if two elements sum up to 0 (such as 0 and 0), it might still return false
:
function problemOne_Solve() {
const k = 0;
const values = [0, 0];
for (i=0; i < values.length; i++) {
if ( values.find( (sum) => { return k-values[i] === sum} ) ) return true;
}
return false;
}
console.log(problemOne_Solve());
To achieve both correct results and reduce computational complexity from O(n ^ 2)
to O(n)
, it's recommended to iterate through the array only once. Create an object where the keys represent the numbers being iterated over, and verify if a key corresponding to target - currNum
exists during each iteration (where target
is the desired sum and currNum
is the current number from the array):
function problemOne_Solve() {
const target = 17;
const values = [11, 15, 3, 8, 2];
const obj = {};
for (const currNum of values) {
if (obj.hasOwnProperty(target - currNum)) {
return true;
}
obj[currNum] = true;
}
return false;
}
console.log(problemOne_Solve());
I was also wondering how I would go about outputting the pair or pairs that sum up to "k," to build further on the solution. I would like to be able to display the pairs on the page, for example.
Instead of immediately returning when a match is found, store the matches in an array and then return that array at the end of the function. Also, instead of setting the object values to true
(or false
), track the occurrences of each number found so far within the object (and decrement the matching number count when a match is identified):
function problemOne_Solve() {
const target = 17;
const values = [11, 15, 3, 8, 2, 17, 0, 0, 17];
const obj = {};
const matches = [];
for (const currNum of values) {
const otherNum = target - currNum;
if (obj[otherNum]) {
obj[otherNum]--;
matches.push([currNum, otherNum]);
}
obj[currNum] = (obj[currNum] || 0) + 1;
}
return matches;
}
console.log(problemOne_Solve());
And there is no such brackets after the if statement, which I thought was required.
When there's a single statement following an if
(or else if
or else
) condition, enclosing brackets are not mandatory, for example:
if (true) console.log('true');
else console.log('this will not log');