javascript - Ramda.js 转换器:平均结果数组
问题描述
我目前正在学习使用 Ramda.js 的传感器。(太有趣了,耶!)
我发现这个问题描述了如何首先过滤数组,然后使用传感器对其中的值求和。
我想做一些类似但不同的事情。我有一组具有时间戳的对象,我想平均时间戳。像这样的东西:
const createCheckin = ({
timestamp = Date.now(), // default is now
startStation = 'foo',
endStation = 'bar'
} = {}) => ({timestamp, startStation, endStation});
const checkins = [
createCheckin(),
createCheckin({ startStation: 'baz' }),
createCheckin({ timestamp: Date.now() + 100 }), // offset of 100
];
const filterCheckins = R.filter(({ startStation }) => startStation === 'foo');
const mapTimestamps = R.map(({ timestamp }) => timestamp);
const transducer = R.compose(
filterCheckins,
mapTimestamps,
);
const average = R.converge(R.divide, [R.sum, R.length]);
R.transduce(transducer, average, 0, checkins);
// Should return something like Date.now() + 50, giving the 100 offset at the top.
当然average
,正如上面所说的那样,它不能工作,因为变换函数的工作方式就像一个减少。
我发现我可以在换能器之后一步完成。
const timestamps = R.transduce(transducer, R.flip(R.append), [], checkins);
average(timestamps);
但是,我认为必须有一种方法可以使用迭代器函数(转换器的第二个参数)来做到这一点。你怎么能做到这一点?或者也许average
必须是transducer
(使用compose
)的一部分?
解决方案
作为第一步,您可以创建一个简单的类型以允许合并平均值。这需要保持对被平均的项目的总和和数量进行统计。
const Avg = (sum, count) => ({ sum, count })
// creates a new `Avg` from a given value, initilised with a count of 1
Avg.of = n => Avg(n, 1)
// takes two `Avg` types and combines them together
Avg.append = (avg1, avg2) =>
Avg(avg1.sum + avg2.sum, avg1.count + avg2.count)
有了这个,我们可以将注意力转向创建将结合平均值的转换器。
首先,一个简单的辅助函数允许将值转换为我们的Avg
类型,并且还包装了一个 reduce 函数以默认为它接收到的第一个值,而不是要求提供初始值(平均值不存在一个好的初始值,所以我们将只使用第一个值)
const mapReduce1 = (map, reduce) =>
(acc, n) => acc == null ? map(n) : reduce(acc, map(n))
然后,转换器只需要组合这些Avg
值,然后将结果平均值从结果中提取出来。null
nb在转换器在空列表上运行的情况下,结果需要保护值。
const avgXf = {
'@@transducer/step': mapReduce1(Avg.of, Avg.append),
'@@transducer/result': result =>
result == null ? null : result.sum / result.count
}
然后,您可以将其作为累加器函数传递给transduce
,它应该会产生结果平均值。
transduce(transducer, avgXf, null, checkins)
推荐阅读
- c# - 根据列表中包含的另一个列表中的属性过滤列表
- flutter - flutter 如何在 silverlist 和 Header 屏幕中提取即将到来的数据和对象
- sql - 添加 where 子句会使查询变慢
- html - 如何使用来自数据框列的值作为每个数据框行的文件名创建一个 html 文件?
- cordova - 如何在 Javascript UWP 应用程序中迭代 IMapView WinRT 对象?
- python - 神经网络输出全1
- python - 在 Python 中对稀疏数据集进行过采样
- javascript - 在索引 2 之后,我在斐波那契数列中得到 NaN
- java - Android - 带有可序列化回调的 DialogFragment 在片段销毁时崩溃
- rust - 尝试在多个线程中使用可变数组切片引用时需要 Lifetime 'static