What is this series about?
Hello all! Welcome to the JavaScript interview questions series. In each post of this series, I will talk about the questions (specific to JavaScript) I faced in my recent interviews. This series will be helpful for you if you are preparing for JavaScript interviews or just started to deep dive into JavaScript and want to test your knowledge.
Post 3: Write your own custom reduce function
In today’s modern web development, a lot of us work on pretty modern tech stacks like React or Vue, or Angular. But in web development, a lot of projects today still function on legacy code and need active work. This is why, writing custom functions or polyfills for new JavaScript features is a popular interview question. Also, writing our own version of something that we use every day makes the concept easy and quick to grasp.
In one of my interviews, the interviewer asked me to write a custom function for Array.reduce()
. Before diving further into this post, we must understand what Array.reduce()
does. Here is a great post on MDN blog on what reduce does.
Now that we are all set, let us dive into writing our own reduce function. 💻 ⚔️
Question
Write a custom function like Array.reduce()
.
// Existing Array.reduce() function
const array = [10, 20, 30, 40];
const reducer = (accumulator, currentValue) => {
return accumulator + currentValue;
}
const result = array.reduce(reducer);
console.log(result);
// expected output: 100
// Your code goes here
function customReduce(arr, reducer, initialValue = 0) {
// Write Code
}
const customResult = customReduce(array, reducer, 0);
console.log(customResult);
Before diving into the solution, I highly suggest that you try to solve this problem on your own. Here is a hint: Think about what reducer expects and what does it return?
Solution
As always, we are going to start with the least and do the obvious stuff first. So we can see that our custom function needs to return the final value.
function customReduce(arr, reducer, initialValue = 0) {
var value;
return value;
}
Further, for each array element, our customReducer
function needs to call the reducer
function (passed in as a parameter). The reducer function expects following parameters:
- The return value from previous execution.
- Current array element
- Current index
- The array itself
function customReduce(arr, reducer, initialValue = 0) {
var value;
for (let i = 0; i < arr.length; i++) {
value = reducer(value, arr[i], i, arr);
}
return value;
}
Now you might be wondering what will happen to the intialValue
? Well, we want intialValue
to be the value passed to the first execution of the reducer
function. We can do that by assigning that intialValue
to value
. So the final version of the customReduce
function will look like this.
Edit:
As rightfully pointed by @kennethlum
, if the initialValue
is not passed, we should consider first element of the array as the initialValue
.
function customReduce(arr, reducer, initialValue = null) {
if (initialValue === null) {
initialValue = arr[0];
}
var value = initialValue;
for (let i = 0; i < arr.length; i++) {
value = reducer(value, arr[i], i, arr);
}
return value
}
Conclusion
Yay!! This looks like a working solution for now. I would love to know what approaches you can come up with for this problem. Do post your suggestions in the comments. And for more interesting questions like this, keep following this series. Until then, Happy Coding!!
Top comments (7)
A simple
reduceRight
using recursion implementation would be like this:The current solution right now as of May 20, 2021, is that it uses
function customReduce(arr, reducer, initialValue = 0) {
which is to assume initialValue is 0, but it can't always be the case.so essentially, one way is that when there is no initial value, we'd use the first value as the initial value instead.
Thank you for pointing out Kenneth. Will edit that part definitely.
I would ding this for lack of input type checking. It's a must especially in a type-silent language.
Helpful.
Nice article.
The for loop should start from 1 if no initial value is provided.
customReduce([1,2,3,4,5], (a,b) => a + b) // 16, but expected 15.
You add 1 twice, first as an initial value, second as the first element of array