Please critique my solution to the "use the reduce Method to Analyze Data"


I have solved this problem a few different ways while trying to get to grips with the reduce method, but I wasn’t really happy with them. My other solutions relied on global variables and/or chaining .filter() or .filter().map() with .reduce().

I was determined to find a way to do it using only .reduce(), and no external variables.

I suspect its probably poor technique for a number of reasons, but I’m still pretty amused that I managed to get it to work at all. What do you think?

var averageRating = watchList.reduce( (a,c,i,arr) => {
    if(a === 0) {
        a = {rating: 0, nolans: 0};

    if(c.Director === "Christopher Nolan") {
        a.rating += Number(c.imdbRating);

    return i < arr.length - 1 ? a : (a.rating / a.nolans);
}, 0);

It doesn’t have much reusability, which doesn’t matter in this case, but not bad overall.

You can just do this to avoid having unnecessary if branch:

watchList.reduce(..., { nolans: 0, rating: 0 })

And use parseFloat() instead of Number()

I often do it this way, if I want to be functional and reusability is a concern:

const by = (key, val) => (obj) => obj[key] === val
const extract = (key) => (obj) => obj[key] 
const toFloat = (str) => parseFloat(str) 

const sum = (a, b) => a + b
const average = (arr) => arr.reduce(sum) / arr.length

const averageRating = average(
    .filter( by('Director', 'Christopher Nolan') )
    .map( extract('imdbRating') )
    .map( toFloat )
1 Like

chain ternary

a===0? a={rating:0, nolans:0}: c.Director ==="Christopher Nolan"? a.nolans++&&a.rating+= parseFloat(c.imdbrating)
1 Like

oh, nice.

I like the way you’ve broken it down, and that seems more functional (which is something I’m just really trying to get a handle on), and I usually like to make things are reusable as possible.

I think I need to spend a bit of time reading over by and extract - I haven’t seen chained arrow notation functions before, and it feels a bit slippery to understand at first glance atm.

What’s the reason for using parseFloat() over Number()? After I wrote my solutions and googled around, I noticed that other people have also gone with parseFloat()

It feels like my brain is melting looking at that, haha!

Do you do code golf by any chance?

You posting a full solution is not a critique of the OP’s solution.

Your code has been blurred out to avoid spoiling a full working solution for other campers who may not yet want to see a complete solution. In the future, please stick to answering the OP’s questions instead of just posting full solutions.

Thank you.

After a few search, I’ve concluded that It doesn’t really matter whether you use parseFloat() or Number() as long as you don’t call the latter with new operator. In general, parseFloat() is less strict than Number(), but they both have inconsistent edge case handling. So, just forget about it I guess.

You don’t really need by and extract, they are just there to enhance readability for averageRating. I had to split it like that to use them in filter and map.

Even if you haven’t seen it before, the concept isn’t so difficult.

fn = (a, b, c) => // use a, b, c
fn = a => b => c =>  // use a, b, c

function fn(a) {
    return function(b) {
        return function(c) {
             //use a, b, c

those functions do the same task, but the second function is more flexible because you can supply arguments across different scopes or you can compose other functions with some pre-supplied arguments.

1 Like

I am looked for ,but how?

I don’t understand what you are asking me.

how to hide code from other?

You wrap the code in [spoiler] and [/spoiler]. It works best when these tags are on their own separate lines. However, the point I was making earlier was about providing hints and suggestions and not just posting full solutions.

I just take half of code from upper and set it in other form. Probably is not functional in exercise.


Seeing it written out in long-form made it click immediately, nice one!