After a few interviews this month I wanted to share a few nice exercises that would come up in technical interviews, and how I originally approached them.
Asynchronous for-loop
This exercise is related to how asynchronous programming work. If you asked me, I would rather ask about how the event loop works instead of asking this particular question.
You are given the following code:
for(var i = 0; i < 10; i++){
setTimeout(() => {
console.log(i);
}, 1000);
}
and you're asked two questions
- what's the output?
- what would you add to print the numbers from 0 to 9
I will leave the first answer as an exercise for the reader but question nĀ°2 should already give you a hint.
To answer the second question what you want is to store for every iteration the value of the variable i
so that they can be accessed later on by the setTimeout
. One of the many alternatives is to create an IIFE (maybe better called IIAF in this case?):
for(var i = 0; i < 10; i++){
(n => {
setTimeout(() => {
console.log(n);
}, 1000);
})(i);
}
Bonus
Would you be able to explain in the comments why this little change works as expected?
for(let i = 0; i < 10; i++){
setTimeout(() => {
console.log(i);
}, 1000);
}
Reduce
The goal of this exercise is to define a function that does exactly the same than Array.prototype.reduce but receiving the array as first parameter (much like lodash's counterpart).
Iterative
This is the most intuitive solution for me, using an accumulator to carry on the result of each function execution.
function reduce(arr, fn, def) {
let accum = def;
for(let i = 0; i < arr.length; i++) {
accum = fn(accum, arr[i]);
}
return accum;
}
Recursive
The recursive version has the requirement of knowing about an specific array operation: removing the first element of an array and get an array with the remaining elements. Of course I didn't knew which function did exactly that from the top of my head and the interviewer was kind enough to mention Array.prototype.slice. It is also important to clarify that Array.prototype.slice
doesn't modifies the array itself but returns a copy of it.
function reduce(arr, fn, def) {
// base case: there are no more elements in the array and the function should finish
if(arr.length === 0) {
return def;
}
return reduce(arr.slice(1), fn, fn(def, arr[0]));
}
Minimalistic
There's a growing interest for tweet-sized solutions, minimizing the characters used for a solution and thought it would be a nice exercise to add it here. I wouldn't recommend to include this type of solutions in your codebase though.
function reduce(arr, fn, def) {
return arr.length === 0 ? def : reduce(arr.slice(1), fn, fn(def, arr[0]));
}
Map
For this exercise you're asked to write a map
function that would replicate the behavior of Array.prototype.map.
Iterative
function map(arr, fn) {
const result = [];
for(const elem of arr) {
result.push(fn(elem));
}
return result;
}
Using reduce
This is when things started to get interesting. I was told to only use the reduce
function previously implemented to write the map function and my first thought was doing something like:
function map(arr, fn) {
const result = [];
reduce(arr, (curr, next) => {
result.push(fn(next));
return curr;
});
return result;
}
which is not incorrect, but was later asked "what if we don't want to use a intermediate variable?" which got me thinking...
function map(arr, fn) {
return reduce(arr, (curr, next) => {
curr.push(fn(next));
return curr;
}, []);
}
Minimalistic
function map(arr, fn) {
return reduce(arr, (curr, next) => curr.push(fn(next)) && curr, []);
}
I've prepared a few playgrounds in CodeSandbox for you to try and solve them if you like:
There are many sites that you can use to practice with similar (or more complex) exercises like Hackerrank or Codility.
Are there any other interesting exercises that you were asked to do? Let me know in the comments!
Top comments (1)
@a0viedo can u explain further why the IIFE and the let worked