7

I'm trying to access the length of the array on which I'm using a reduce function inside that reduce, but I don't seem to be able to do it, does anyone have any idea if it is possible to access the array object inside any of the higher order functions?

PS: I tried using this but to no success;

PSS: I want to calculate the average rating using a reduce function, so I use the reduce to sum all values in the array and divide those same values by the array length, like so:

let averageRating = watchList
    .filter(movie => movie.Director === 'Christopher Nolan')
    .map(x => parseFloat(x.imdbRating))
    .reduce((total, current) => total + (current / 'array length'));

where 'array length' would be, you guessed it, the array length.

PSSS: Tried

var averageRating = watchList
  .filter(movie => movie.Director === 'Christopher Nolan')
  .map(x => parseFloat(x.imdbRating))
  .reduce((total, current, index, arr) => total + (current / arr.length));

but the array length keeps changing as the array is being reduced, so it wouldn't work for my purposes.

4
  • 1
    Please share some of your code. It's easier to help you out if you have code. Commented Feb 26, 2018 at 1:14
  • if you assign it to a var before the reduce and use that? Commented Feb 26, 2018 at 1:15
  • i could do that, but i really wanted to find a way to access it inside the reduce, but it doesn't seem possible :( Commented Feb 26, 2018 at 1:18
  • 3
    reduce is supplied four parameters: the accumulator, the current array value, its index, and the array itself. If you give your callback four parameters, that last one will be the array and you can get its length. Commented Feb 26, 2018 at 1:19

2 Answers 2

4

This should do it:

let averageRating = watchList
    .filter(movie => movie.Director === 'Christopher Nolan')
    .map(x => parseFloat(x.imdbRating))
    .reduce((total, current, idx, arr) => total + (current / arr.length));

Update

If you're interested in seeing how I would do it in my preferred library, Ramda (disclaimer: I'm one of its principle authors) the code would like like this:

const {pipe, filter, propEq, pluck, map, mean} = R;

const watchList = [{"Director": "Christopher Nolan", "imdbRating": 4.6, "title": "..."}, {"Director": "Michel Gondry", "imdbRating": 3.9, "title": "..."}, {"Director": "Christopher Nolan", "imdbRating": 2.8, "title": "..."}, {"Director": "Christopher Nolan", "imdbRating": 4.9, "title": "..."}, {"Director": "Alfred Hitchcock", "imdbRating": 4.6, "title": "..."}, {"Director": "Christopher Nolan", "imdbRating": 4.6, "title": "..."}];

const averageRating = pipe(
  filter(propEq('Director', 'Christopher Nolan')),
  pluck('imdbRating'),
  map(Number),
  mean
);

console.log(averageRating(watchList));
<script src="//cdnjs.cloudflare.com/ajax/libs/ramda/0.25.0/ramda.js"></script>

I find this leads to really clean, readable code.

Sign up to request clarification or add additional context in comments.

11 Comments

I tried it, but I needed the array length as a constant and it changes as the array is reduced, so the average is wrong in the end.
reduce does not change the array on its own. What is changing it?
That's fine. I'm still trying to figure out what's happening in your case. Can you supply details of what's changing your array? Is it some other data structure (similar to a NodeList or arguments) that's array-like but not an array?
You're right, I was just doing some testing and figured that if i didn't give a initialValue of 0 the average would end up double the amount it was supposed to
just adding the initialValue fixed it for me.
|
3

You can try this:

let averageRating = watchList
        .filter(movie => movie.Director === 'Christopher Nolan')
        .map(x => parseFloat(x.imdbRating))
        .reduce((total, current, index, array) => {
            total += current;
            if( index === array.length - 1) {
               return total/array.length;
            } else {
               return total;
            }
        });

1 Comment

this would work as well, but for some reason I wanted to divide each value by the length to take fewer lines, but thanks :D

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.