🔥 JavaScript Interview Series(10): Functional Programming — map, reduce, filter Explained


Functional programming is a hot topic in JavaScript interviews. Hiring managers want to see that you can write clean, predictable, and maintainable code. Mastering the array methods map, filter, and reduce is a fantastic way to demonstrate these skills. Let’s dive into some common interview questions that will test your understanding of these powerful tools.




1. What’s the fundamental difference between map, filter, and reduce?

Key Concept: This question assesses your high-level understanding of the purpose of each method.

Standard Answer: The fundamental difference lies in what they do and what they return.

  • map transforms each element in an array and returns a new array of the same length with the transformed elements. Think of it as creating a one-to-one mapping from the original array to a new one.

    const numbers = [1, 2, 3];
    const doubled = numbers.map(num => num * 2); // [2, 4, 6]
    
  • filter creates a new array containing only the elements that pass a specific condition. The new array’s length can be less than or equal to the original array’s length.

    const numbers = [1, 2, 3, 4, 5];
    const evens = numbers.filter(num => num % 2 === 0); // [2, 4]
    
  • reduce iterates over an array and returns a single value. This value is the result of a “reducer” function that accumulates a value from each element.

    const numbers = [1, 2, 3, 4, 5];
    const sum = numbers.reduce((accumulator, current) => accumulator + current, 0); // 15
    

Possible 3 Follow-up Questions: 👉 (Want to test your skills? Try a Mock Interview — each question comes with real-time voice insights)

  1. Can you describe a scenario where you would choose to use forEach over map?
  2. Do any of these methods mutate the original array?
  3. How would you explain the concept of a “higher-order function” in the context of these methods?



2. Can you implement your own version of the map method?

Key Concept: This tests your deeper understanding of how map works under the hood and your ability to work with functions as first-class citizens.

Standard Answer: Absolutely. My custom map function would iterate over each element of an array, apply a callback function to it, and push the result into a new array.

Array.prototype.myMap = function(callback) {
  const newArray = [];
  for (let i = 0; i < this.length; i++) {
    newArray.push(callback(this[i], i, this));
  }
  return newArray;
};

const numbers = [1, 2, 3];
const doubled = numbers.myMap(num => num * 2); // [2, 4, 6]
Enter fullscreen mode

Exit fullscreen mode

This implementation mimics the behavior of the native map method by creating a new array and populating it with the results of the callback function.

Possible 3 Follow-up Questions: 👉 (Want to test your skills? Try a Mock Interview — each question comes with real-time voice insights)

  1. Why is it generally not a good idea to modify the Array.prototype directly in a production application?
  2. How would you add support for the thisArg parameter that the native map method has?
  3. What are the potential performance implications of your implementation compared to the native one?



3. How would you use filter to remove all falsy values from an array?

Key Concept: This question checks your knowledge of truthy and falsy values in JavaScript and how to apply that to filter.

Standard Answer: A concise way to do this is to pass the Boolean constructor directly to the filter method.

const mixedArr = [0, 1, false, 2, '', 3, null, 'a', undefined, NaN];
const truthyArr = mixedArr.filter(Boolean); // [1, 2, 3, 'a']
Enter fullscreen mode

Exit fullscreen mode

The filter method calls the Boolean constructor for each element. The constructor coerces each element to its boolean equivalent, and filter keeps only the ones that are true.

Possible 3 Follow-up Questions: 👉 (Want to test your skills? Try a Mock Interview — each question comes with real-time voice insights)

  1. Could you write the same logic using an arrow function instead of the Boolean constructor?
  2. What if the requirement was to remove only null and undefined values? How would your solution change?
  3. Can you explain the concept of “type coercion” in the context of this solution?



4. Explain the arguments of the reduce method’s callback function.

Key Concept: This assesses your detailed knowledge of the reduce method’s signature.

Standard Answer: The callback function for reduce takes four arguments:

  1. accumulator: This is the value that gets accumulated. It’s the return value of the previous invocation of the callback. On the first call, it’s the initialValue if one is provided.
  2. currentValue: The current element being processed in the array.
  3. currentIndex (optional): The index of the currentValue.
  4. array (optional): The array reduce was called upon.
const numbers = [10, 20, 30];
numbers.reduce((accumulator, currentValue, currentIndex, array) => {
  console.log(`Accumulator: ${accumulator}, Current Value: ${currentValue}, Index: ${currentIndex}`);
  return accumulator + currentValue;
}, 0);
Enter fullscreen mode

Exit fullscreen mode

Possible 3 Follow-up Questions: 👉 (Want to test your skills? Try a Mock Interview — each question comes with real-time voice insights)

  1. What happens if you don’t provide an initialValue to reduce?
  2. Can you provide an example of when currentIndex and array might be useful?
  3. How would you use reduce to flatten an array of arrays?



5. You have an array of objects. How would you use map and filter together to get the names of all users who are over 18?

Key Concept: This tests your ability to chain these methods to perform more complex data transformations.

Standard Answer: I would first use filter to get an array of users who are over 18, and then I would chain map to that result to extract just their names.

const users = [
  { name: 'Alice', age: 25 },
  { name: 'Bob', age: 17 },
  { name: 'Charlie', age: 32 },
  { name: 'David', age: 16 }
];

const adultNames = users
  .filter(user => user.age > 18)
  .map(user => user.name); // ['Alice', 'Charlie']```
{% endraw %}

This is a very common and readable pattern in functional programming.

**Possible 3 Follow-up Questions:** 👉 ([Want to test your skills? Try a Mock Interview  each question comes with real-time voice insights](https://offereasy.ai))
1.  Could this be achieved with a single {% raw %}`reduce`{% endraw %}? If so, which approach would you prefer and why?
2.  What are the performance considerations when chaining multiple array methods?
3.  How would you handle a situation where the {% raw %}`age`{% endraw %} property might be missing on some user objects?

***

## 6. How can you use {% raw %}`reduce`{% endraw %} to group an array of objects by a specific property?

**Key Concept:** This is a more advanced {% raw %}`reduce`{% endraw %} question that demonstrates your ability to use it for more than just simple accumulations.

**Standard Answer:** You can use {% raw %}`reduce`{% endraw %} to transform an array into an object. The accumulator, in this case, would be the object you're building.
{% raw %}


```javascript
const people = [
  { name: 'Alice', city: 'New York' },
  { name: 'Bob', city: 'London' },
  { name: 'Charlie', city: 'New York' }
];

const peopleByCity = people.reduce((acc, person) => {
  const city = person.city;
  if (!acc[city]) {
    acc[city] = [];
  }
  acc[city].push(person);
  return acc;
}, {});

/*
Result:
{
  'New York': [ { name: 'Alice', city: 'New York' }, { name: 'Charlie', city: 'New York' } ],
  'London': [ { name: 'Bob', city: 'London' } ]
}
*/
Enter fullscreen mode

Exit fullscreen mode

Possible 3 Follow-up Questions: 👉 (Want to test your skills? Try a Mock Interview — each question comes with real-time voice insights)

  1. Can you explain what the initial value {} does in this example?
  2. How could you make this grouping function more generic so it can group by any given property?
  3. What are some alternative ways to achieve this without using reduce?



7. Is it possible to have an asynchronous callback function with map? What would be the result?

Key Concept: This question tests your understanding of how these synchronous array methods interact with asynchronous JavaScript.

Standard Answer: Yes, you can pass an async function to map, but the result might not be what you expect. map itself is synchronous and will not wait for the promises to resolve. The result will be an array of Promises.

const ids = [1, 2, 3];

const fetchData = async (id) => {
  // Simulate an API call
  return new Promise(resolve => setTimeout(() => resolve(`Data for ${id}`), 100));
};

const promises = ids.map(async (id) => {
  return await fetchData(id);
});

console.log(promises); // [Promise, Promise, Promise]
Enter fullscreen mode

Exit fullscreen mode

To get the actual data, you would need to use Promise.all to wait for all the promises to resolve.

Possible 3 Follow-up Questions: 👉 (Want to test your skills? Try a Mock Interview — each question comes with real-time voice insights)

  1. How would you modify the code to get the final array of data?
  2. What are the potential drawbacks of firing off multiple network requests like this in parallel?
  3. How would forEach behave differently with an async callback compared to map?



8. Can you use map or filter on an object?

Key Concept: This question probes your understanding of what data types these methods are designed for.

Standard Answer: map and filter are methods on the Array.prototype, so they can’t be directly used on an object. However, you can use them on the keys, values, or entries of an object by first converting them into an array using Object.keys(), Object.values(), or Object.entries().

const myObj = { a: 1, b: 2, c: 3 };

// Map over the values and double them
const doubledValues = Object.values(myObj).map(value => value * 2); // [2, 4, 6]

// Filter out key-value pairs where the value is not even
const evenEntries = Object.entries(myObj).filter(([key, value]) => value % 2 === 0);
// [['b', 2]]```
{% endraw %}


**Possible 3 Follow-up Questions:** 👉 ([Want to test your skills? Try a Mock Interview  each question comes with real-time voice insights](https://offereasy.ai))
1.  How would you convert the {% raw %}`evenEntries`{% endraw %} array back into an object?
2.  Are there any performance implications to be aware of when converting an object to an array and back?
3.  Can you describe a scenario where you would prefer to use a {% raw %}`for...in`{% endraw %} loop over these methods for an object?

***

## 9. When would you prefer using {% raw %}`reduce`{% endraw %} over a combination of {% raw %}`map`{% endraw %} and {% raw %}`filter`{% endraw %}?

**Key Concept:** This question assesses your ability to reason about code efficiency and readability.

**Standard Answer:** You might prefer {% raw %}`reduce`{% endraw %} when you need to perform both a mapping and a filtering operation in a single pass. This can be more efficient as it avoids creating an intermediate array that the {% raw %}`filter`{% endraw %} and {% raw %}`map`{% endraw %} chain would produce.

For example, to get the sum of the squares of all even numbers:
{% raw %}


```javascript
const numbers = [1, 2, 3, 4, 5];

// Using map and filter
const sumOfSquaresOfEvens = numbers
  .filter(num => num % 2 === 0)
  .map(num => num * num)
  .reduce((acc, num) => acc + num, 0); // 20

// Using a single reduce
const sumWithReduce = numbers.reduce((acc, num) => {
  if (num % 2 === 0) {
    return acc + (num * num);
  }
  return acc;
}, 0); // 20
Enter fullscreen mode

Exit fullscreen mode

While the single reduce is more performant, the chained map and filter approach can often be more readable. The choice depends on the specific use case and a balance between performance and clarity.

Possible 3 Follow-up Questions: 👉 (Want to test your skills? Try a Mock Interview — each question comes with real-time voice insights)

  1. Can you think of a situation where the readability of chained methods would be a more important factor than the minor performance gain of a single reduce?
  2. Are there any new JavaScript features or proposals that might offer an alternative to this?
  3. How does the size of the array impact your decision here?



10. How do map, filter, and reduce relate to the principles of functional programming?

Key Concept: This high-level question connects the practical use of these methods to broader programming paradigms.

Standard Answer: map, filter, and reduce are excellent examples of functional programming principles in JavaScript.

  • Pure Functions: The callback functions passed to these methods are often pure. They take an input and produce an output without side effects, meaning they don’t modify external state.
  • Immutability: These methods do not mutate the original array. Instead, they return a new array or value, which is a core tenet of functional programming.
  • Declarative vs. Imperative: They allow for a more declarative style of programming. You describe what you want to do (e.g., “filter for even numbers”) rather than how to do it with loops and conditionals.

This leads to code that is often more predictable, easier to reason about, and less prone to bugs.

Possible 3 Follow-up Questions: 👉 (Want to test your skills? Try a Mock Interview — each question comes with real-time voice insights)

  1. Can you give an example of an impure function that you could pass to one of these methods? What would be the potential problems with that?
  2. What is function composition, and how can it be used with these methods?
  3. Besides map, filter, and reduce, what are some other array methods in JavaScript that align with functional programming principles?



Source link

Leave a Reply

Your email address will not be published. Required fields are marked *