在高阶函数中访问数组对象

7

我想要在使用reduce函数的数组上访问其长度,在这个reduce函数里面,但是我好像做不到,有没有人知道是否可以在任何高阶函数中访问数组对象?

PS: 我已经尝试使用 this 了,但没有成功;

PSS: 我想要使用reduce函数计算平均评分,所以我使用reduce来对数组中所有值求和,并将这些值除以数组长度得出结果,代码如下:

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

“array length”指的是数组的长度。

PSSS: 尝试过

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

但是,由于数组正在缩小,因此数组长度不断变化,所以它对我的目的没有用。


1
请分享一些你的代码。如果你有代码,那么更容易帮助你解决问题。 - Aditya R
如果在 reduce 之前将其分配给一个变量并使用它,会怎样? - Giannis Mp
我本来可以这样做,但我真的想找到一种在 reduce 内部访问它的方法,但似乎不可能 :( - edmassarani
3
reduce 接受四个参数:累加器、当前数组值、其索引和整个数组本身。如果你的回调函数接受了四个参数,最后一个参数就是整个数组,你可以通过它获取数组的长度。请注意不要改变原文意思。 - Scott Sauyet
2个回答

4
这应该可以解决问题:
let averageRating = watchList
    .filter(movie => movie.Director === 'Christopher Nolan')
    .map(x => parseFloat(x.imdbRating))
    .reduce((total, current, idx, arr) => total + (current / arr.length));

更新

如果您想看看我如何在我喜欢的库Ramda中实现它(免责声明:我是主要作者之一)代码如下:

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>

我发现这会导致非常清晰易读的代码。

我尝试过了,但我需要将数组长度作为常量,并且随着数组的减少而改变,因此最终平均值是错误的。 - edmassarani
2
“reduce”本身不会改变数组。那是什么在改变它呢? - Scott Sauyet
没问题。我还在努力弄清楚你的情况发生了什么。你能提供一些细节,说明是什么改变了你的数组吗?它是否类似于NodeListarguments这样的其他数据结构,它们类似于数组但不是数组? - Scott Sauyet
1
你说得对,我只是在做一些测试,发现如果我没有给定初始值为0,平均值将会是预期值的两倍。 - edmassarani
只是添加了initialValue就解决了我的问题。 - edmassarani
显示剩余6条评论

3
您可以尝试以下方法:
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;
            }
        });

这个也可以,但出于某种原因,我想将每个值除以长度以减少行数,不过还是谢谢:D - edmassarani

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接