Reputation: 31
I was wondering if someone could explain to me the following solution:
function smallestInt(arr) {
if (arr.length === 1) return arr[0];
return (Math.min(arr[0],smallestInt(arr.slice(1))));
}
console.log(smallestInt([42, 12, 8, 60, 12, 33, 21])); // 8
In particular, what the stack would look like. Any input would be greatly appreciated.
Upvotes: 0
Views: 219
Reputation: 18901
Using console.log
is great for quick debugging. It's easy to reach for and is a great tool to have in your box but it is not the only one. There's much to be gained in learning how to use a debugger too.
Sources
tabThe debugger will now stop every single time L2 is reached. See the screencast below. Note how the debugger displays the current state of arr
in the top right corner:
Another thing you can do is "go back in time". Note how we can inspect each step in the stack back and forth. (See bottom right.)
Unless it is an exercise you don't need recursion for this. Here are a couple of alternatives:
Math.min(...[42, 12, 8, 60, 12, 33, 21]);
//=> 8
Or with reduce:
[42, 12, 8, 60, 12, 33, 21].reduce((n, x) => Math.min(n, x), Infinity)
//=> 8
Upvotes: 1
Reputation: 3714
Lets take small array [42, 12, 8, 60]
So Its start with finding min value between 42 and result returned by resursive call to smallestInt([12, 8, 60])
. Here we call smallestInt
by removing 1st index element from our array.
If we were to expand this call stack out, it would look like this:
smallestInt([42, 12, 8, 60]) = Math.min(42, smallestInt([12, 8, 60]));
Now our previous smallestInt
call will have more than 1 length array so it does make further recursive call to self by setting 1st element as a first parameter to Math.min
and second parameter as calling smallestInt
with array removing 1st index element. i.e. 12. So our call stack will looks like this.
smallestInt([42, 12, 8, 60]) = Math.min(42, Math.min(12, smallestInt([8, 60]));
And again same as previous:
smallestInt([42, 12, 8, 60]) = Math.min(42, Math.min(12, Math.min(8, smallestInt([60]))));
Since now our smallestInt([60])
gets 1 length array [60]
as input; if (arr.length === 1)
condition gets satisfied. i.e smallestInt
will return 60. And we break out of recursive call.
Now It starts traversing reverse. ie. It will start finding min value.
smallestInt([42, 12, 8, 60]) = Math.min(42, Math.min(12, Math.min(8, 60)));
smallestInt([42, 12, 8, 60]) = Math.min(42, Math.min(12, 8));
smallestInt([42, 12, 8, 60]) = Math.min(42, 8);
smallestInt([42, 12, 8, 60]) = 8;
And finally returns 8;
Upvotes: 0
Reputation: 25408
The following steps can be log output as
let stage = 0;
function smallestInt(arr) {
console.log(`arr = [${arr}]`);
if (arr.length === 1) return arr[0];
let temp, newArr;
const min = Math.min(arr[0], temp = smallestInt(newArr = arr.slice(1)));
console.log(`stage: ${stage++} => Math.min(arr[0] = ${arr[0]}, smallestInt( arr.slice(1)) = [${newArr}] = ${min}`)
return min;
}
console.log(smallestInt([42, 12, 8, 16]));
/* This is not a part of answer. It is just to give the output fill height. So IGNORE IT */
.as-console-wrapper { max-height: 100% !important; top: 0; }
Let's go process step by step
1) When the function starts
arr = [42,12,8,16]
NOTE: and we know that arr.length is not equal to 1
so it won't return arr[0]
and we are returning the result value of
Math.min(arr[0],smallestInt(arr.slice(1)))
which can be interpreted as:
Math.min(arr[0] = 42, smallestInt( arr.slice(1)) = [12,8,16] // recursion here
2) When the function starts
arr = [12,8,16]
NOTE: and we know that arr.length is not equal to 1
so it won't return arr[0]
and we are returning the result value of
Math.min(arr[0],smallestInt(arr.slice(1)))
which can be interpreted as:
Math.min(arr[0] = 12, smallestInt( arr.slice(1)) = [8,16] // recursion here
3) When the function starts
arr = [8,16]
NOTE: and we know that arr.length is not equal to 1
so it won't return arr[0]
and we are returning the result value of
Math.min(arr[0],smallestInt(arr.slice(1)))
which can be interpreted as:
Math.min(arr[0] = 8, smallestInt( arr.slice(1)) = [16] // recursion here
4) When the function starts
arr = [16]
NOTE: The arr.length is equal to 1
so it will return arr[0]
that is 16
3) Now the value returned from smallestInt( newArr = arr.slice( 1 ) )
is 16
so the returned value of function will be
Math.min(8, 16) ===> 8 will be out returned value of whole function
2) Now the value returned from smallestInt( newArr = arr.slice( 1 ) )
is 8
so the returned value of function will be
Math.min(12, 8) ===> 8 will be out returned value of whole function
1) Now the value returned from smallestInt( newArr = arr.slice( 1 ) )
is 8
so the returned value of function will be
Math.min(42, 8) ===> 8 will be out returned value of whole function
So the final value of console.log( smallestInt( [42, 12, 8, 16] ) );
will be 8
Upvotes: 0
Reputation: 2270
this is simply comparing the last and the second last index and selecting the smaller in each step.
// You can print it with slight rearrangement of the code
function smallestInt(arr) {
if (arr.length === 1) return arr[0];
let last = smallestInt(arr.slice(1))
let res = (Math.min(arr[0], last));
console.log(arr[0], last, res);
return res;
}
console.log(smallestInt([42, 12, 8, 60, 12, 33, 21]));
Upvotes: 0