Using reduce() - Use Higher-Order Functions map, filter, or reduce to Solve a Complex Problem

I completed this challenge using map() and filter(), quite naturally.

const squareList = arr => {
  const positiveInt = arr.filter(number => (Number.isInteger(number) && number > 0))
  const squaredInt = positiveInt.map(number => number * number);
  return squaredInt;
};

const squaredIntegers = squareList([-3, 4.8, 5, 3, -3.2]);
console.log(squaredIntegers);

So I went to the guide and see that they have another solution using reduce():

const squareList = arr => {
  return arr.reduce((sqrIntegers, num) => {
    return Number.isInteger(num) && num > 0
      ? sqrIntegers.concat(num * num)
      : sqrIntegers;
  }, []);
};

which to me seems rather unintuitive.

Since I’m still very new to JavaScript, should I try to understand both solutions and solve the problem in as many different ways as possible, not just this challenge but to form a learning habit? I feel like this is one of the more important things when learning to code, but I don’t know how other people usually approach this, so I’m asking this question.

2 Likes

Whether or not something is “intuitive” is relative. The more you use it, the more comfortable it becomes. I would agree that it is slightly less “readable” in that it combines two “steps” into one, it takes a couple extra seconds of reading.

Which is better? It depends. The reduce function is slightly more efficient (one pass through the data) . Is that better? To give up a little bit of readability for a little bit of efficiency? Again, for me, that depends. If I can wrap that in a well-named function that does only that so it is completely clear what it does, then to me, the reduce solution is better. If it is in the flow of code and I am worried that it may not be obvious what it is doing, I might go for the two step solution. Besides, 99.99% of the time, that difference in performance won’t matter.

should I try to understand both solutions and solve the problem in as many different ways as possible, not just this challenge but to form a learning habit?

I think that is a great learning strategy. I often do that, after finishing an algorithm challenge, figure out how other people solved it.

Specifically on reduce it is very cool and powerful but often frighten’s off learners. I think it is the hardest one for learners to master. But it also can do really cool things when used well.

1 Like

You should take the effort to understand how it works: it can be very useful. Every other array method can be implemented using reduce, it’s quite powerful.

That said

Yes, I have a linting rule in my current codebase at work that forbids use of reduce unless it’s just being for adding up an array of numbers, it will flag any usage of the method and suggest using a for…of loop instead

1 Like

That made me laugh. I think that’s a bit extreme, but I do agree that you can create some rather arcane an impenetrable code with reduce. But I usually just wrap the callback into a well-named function.

But yeah, it can get a little awkward in some usages. I can understand why people might want to avoid it. Where I’m working now, they prefer methods, putting an emphasis on declarative programming.

But we both agree that it should be learned.

2 Likes

Thanks for taking the time to answer! You gave me some understanding of what option to take. And I’ll definitely take another stab at reduce()!

Haha, it’s part of a package of eslint rules I added to help with making sure ESModules worked, which also a load of preferences based on newer features + simpler code. I turned off a load of them but ended up keeping the reduce one after one of the other developers got completely stuck on some reducer logic I’d written that I thought was relatively simple. So far, haven’t found anywhere that couldn’t be rewritten in a much simpler form. But I tend to find that I rarely need to chain methods together, map/filter/flatMap are normally all I need. If it weren’t the case reduce would be more useful but :man_shrugging:t3:

Edit: IME when doing anything complicated with reduce it often ends up shoehorning complicated logic into a the quite specific recursive callback, into quite a small space. Can do filter/map/etc first, but I tend to end up writing a single function that does the operation

This is really crazy!

I also used this solution, but declared one new variable.

const squareList = arr => {
  const newArr = arr
    .filter(el => Number.isInteger(el) && el > 0)
    .map(el => el *= el);
  return newArr;
};

const squaredIntegers = squareList([-3, 4.8, 5, 3, -3.2]);
console.log(squaredIntegers);

I’ve edited your post for readability. When you enter a code block into a forum post, please precede it with a separate line of three backticks and follow it with a separate line of three backticks to make it easier to read.

You can also use the “preformatted text” tool in the editor (</>) to add backticks around text.

See this post to find the backtick on your keyboard.
Note: Backticks (`) are not single quotes (').

1 Like

I also wrapped it in [spoiler][/spoiler] tags since it is a working solution to a curriculum challenge.

Can you use an extra variable there. Sure? Is there anything wrong with that? Maybe a little. It is an unnecessary variable. The function name should imply that it is returning an array so it is a little redundant. I think things like sonar would flag that as unnecessary. It’s not the end of the world, but it it’s basically a one statement process that’s being spread into two statements, one could argue that it is unnecessary. It’s not a huge sin, but a tiny one, perhaps, at least according to some.

1 Like

I’d say the name of the variable is the bigger issue, not so much the variable itself.

It might be redundant no matter what, but that is doubly true if it also provides no useful information. The name newArr is pretty useless as we know both filter and map return a new array. If it at least signified what it contained it might have some purpose, although as said the function, in this case, can provide that information.

If you had saved the result of filter out into an intermediate variable it might have provided information about what the filter is doing.

2 Likes

This topic was automatically closed 182 days after the last reply. New replies are no longer allowed.