【问题标题】:Standard function for iteratively accumulating while yielding related values用于迭代累加同时产生相关值的标准函数
【发布时间】:2014-09-17 17:55:19
【问题描述】:

时不时会出现一种特殊的计算风格,我不知道如何很好地转换为 map/filter/reduce。我想知道是否有一个标准的函数式函数可以做到这一点,或者一个好名字是什么。

基本上,您会发现自己遵循指示,同时在每个站点都让步。这是一个展示总体思路的 C# 函数:

public static IEnumerable<TOut> streamAggregateMap<TDif, TAcc, TOut>(
        this IEnumerable<TDif> difs,
        TAcc seed,
        Func<TAcc, TDif, TAcc> accumulator,
        Func<TAcc, TDif, TOut> selector) {
    var acc = seed;
    foreach (var dif in difs) {
        yield return selector(acc, dif);
        acc = accumulator(acc, dif);
    }
}

您可以使用它在生成值的同时追踪一棵树:

var vals = goLeftDirections.streamAggregateMap(
    root,
    (node, goLeft) => goLeft ? node.left : node.right,
    (node, goLeft) => node.value);

或者告诉你通过迭代乘以 2 并添加一些偏移量得到的数字的质因式分解,除了因式分解是数字偏移而不乘以 2:

var factorizations = offsets.streamAggregateMap(
    1,
    (total, offset) => total * 2 + offset,
    (total, offset) => (total + offset).Factorize());

这种“在产生相关值的同时累积”功能是否有标准名称?要使用的标准函数?

【问题讨论】:

    标签: c# functional-programming nomenclature


    【解决方案1】:

    MoreLINQ 将此操作称为Scan

    【讨论】:

    • 您将如何在扫描方面实现我的分解示例?
    • @Strilanc offsets.Scan(new{total = 1, offset = 0}, (acc, offset) =&gt; new{total = total * 2 + offset, offset}).Select(acc =&gt; (acc.total + offset).Factorize())Scan 不应用单独的选择器来产生和累加,因此在您的实现方面可以明智地实现 Scan,但是聚合值和产生的概念性想法是两个操作都在执行的。 MoreLinq 的设计者显然只是没有想到为什么有人会想要产生一个新的总数以外的值。话虽如此,正如我所展示的,您可以使用Scan + Select
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2019-11-13
    • 1970-01-01
    • 2013-10-15
    • 2018-10-26
    • 1970-01-01
    • 1970-01-01
    • 2019-11-27
    相关资源
    最近更新 更多