Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

access the array object inside a higher order function

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.

like image 532
edmassarani Avatar asked Feb 26 '18 01:02

edmassarani


2 Answers

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.

like image 150
Scott Sauyet Avatar answered Sep 20 '22 14:09

Scott Sauyet


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;
            }
        });
like image 45
Giannis Mp Avatar answered Sep 22 '22 14:09

Giannis Mp