C#提高:函数式编程中常见的 `map`、`filter`、`reduce` 的类似操作-由Deepseek产生

在 C# 中,函数式编程中常见的 mapfilterreduce 操作可以通过 LINQ(Language Integrated Query) 方便地实现。它们分别对应以下方法:

函数式操作 C# LINQ 方法 说明
map Select 将序列中的每个元素映射为新形式
filter Where 根据条件筛选元素
reduce Aggregate 对序列进行累积计算(累加、累乘等)

下面给出一个完整的示例,演示如何对一个整数列表依次进行筛选(filter)、映射(map)和归约(reduce)。

csharp 复制代码
using System;
using System.Linq;
using System.Collections.Generic;

public class Program
{
    public static void Main()
    {
        List<int> numbers = new List<int> { 1, 2, 3, 4, 5, 6 };

        // filter: 保留偶数
        var filtered = numbers.Where(n => n % 2 == 0);
        // map: 每个数平方
        var mapped = filtered.Select(n => n * n);
        // reduce: 求和
        int result = mapped.Aggregate((acc, n) => acc + n);

        // 可以链式调用,一气呵成
        int result2 = numbers
                        .Where(n => n % 2 == 0)   // filter
                        .Select(n => n * n)       // map
                        .Aggregate((acc, n) => acc + n); // reduce

        Console.WriteLine($"结果: {result}");   // 输出 56 (4+16+36)
        Console.WriteLine($"链式结果: {result2}"); // 同样输出 56
    }
}

常用变体与说明

  • Select 可以投射出新的类型,例如 .Select(x => new { Name = x })
  • Where 可以串联使用,进一步细化筛选条件。
  • Aggregate 可以指定种子值,例如 Aggregate(0, (acc, n) => acc + n),等价于 Sum();但 Aggregate 更通用,可以实现累乘、拼接字符串等。
  • 如果只是简单的求和、求平均、求最大值等,可以使用专用方法 Sum()Average()Max()Min() 等,它们都是归约操作的简化版。

查询表达式语法(可选)

除了方法语法,C# 还提供了查询表达式语法,更接近 SQL:

csharp 复制代码
var result = (from n in numbers
              where n % 2 == 0
              select n * n).Sum();

这种方法在复杂查询时可读性更好,但归约操作通常仍需使用方法语法(如 Sum())。

总结

在 C# 中,利用 LINQ 可以轻松实现函数式编程中的核心操作,且代码简洁、类型安全。以上示例展示了 mapfilterreduce 的对应实现,实际开发中可根据需求组合使用。

当然可以。不使用 LINQ,我们完全可以通过普通循环委托 手动实现类似 mapfilterreduce 的功能。下面提供两种常见的实现方式:直接使用循环 ,或自定义扩展方法 (无需 System.Linq 命名空间)。


1. 直接使用循环

最原始的方式就是显式编写 foreachfor 循环,依次进行筛选、转换和累积。

csharp 复制代码
using System;
using System.Collections.Generic;

class Program
{
    static void Main()
    {
        List<int> numbers = new List<int> { 1, 2, 3, 4, 5, 6 };

        // filter: 保留偶数
        List<int> filtered = new List<int>();
        foreach (var n in numbers)
        {
            if (n % 2 == 0)
                filtered.Add(n);
        }

        // map: 每个数平方
        List<int> mapped = new List<int>();
        foreach (var n in filtered)
        {
            mapped.Add(n * n);
        }

        // reduce: 求和
        int result = 0;
        foreach (var n in mapped)
        {
            result += n;
        }

        Console.WriteLine(result); // 56
    }
}

这种方式直观,但代码冗长,且每一步都要创建中间集合,不适合大型数据流。


2. 自定义扩展方法(模拟 LINQ 风格)

我们可以自己实现类似 SelectWhereAggregate 的扩展方法,完全脱离 System.Linq。这些方法内部仍然使用循环,但提供了链式调用的优雅语法。

csharp 复制代码
using System;
using System.Collections.Generic;

public static class MyLinqExtensions
{
    // 模拟 Select (map)
    public static IEnumerable<TResult> MySelect<TSource, TResult>(
        this IEnumerable<TSource> source,
        Func<TSource, TResult> selector)
    {
        foreach (var item in source)
        {
            yield return selector(item);
        }
    }

    // 模拟 Where (filter)
    public static IEnumerable<TSource> MyWhere<TSource>(
        this IEnumerable<TSource> source,
        Func<TSource, bool> predicate)
    {
        foreach (var item in source)
        {
            if (predicate(item))
                yield return item;
        }
    }

    // 模拟 Aggregate (reduce)
    public static TAccumulate MyAggregate<TSource, TAccumulate>(
        this IEnumerable<TSource> source,
        TAccumulate seed,
        Func<TAccumulate, TSource, TAccumulate> func)
    {
        TAccumulate result = seed;
        foreach (var item in source)
        {
            result = func(result, item);
        }
        return result;
    }
}

class Program
{
    static void Main()
    {
        List<int> numbers = new List<int> { 1, 2, 3, 4, 5, 6 };

        int result = numbers
                        .MyWhere(n => n % 2 == 0)   // filter
                        .MySelect(n => n * n)       // map
                        .MyAggregate(0, (acc, n) => acc + n); // reduce

        Console.WriteLine(result); // 56
    }
}

关键点

  • 使用 yield return 实现延迟执行(流式处理),避免中间集合。
  • Func 委托让调用者自定义逻辑。
  • 这些方法本质上就是 LINQ 内部实现方式的简化版,但完全不需要引用 System.Linq 命名空间。

3. 使用普通静态方法(不依赖扩展方法)

如果不喜欢扩展方法,也可以直接写静态方法,手动传入集合和委托:

csharp 复制代码
public static class MyFunctions
{
    public static IEnumerable<T> Filter<T>(IEnumerable<T> source, Func<T, bool> predicate)
    {
        foreach (var item in source)
            if (predicate(item))
                yield return item;
    }

    public static IEnumerable<TResult> Map<TSource, TResult>(IEnumerable<TSource> source, Func<TSource, TResult> mapper)
    {
        foreach (var item in source)
            yield return mapper(item);
    }

    public static TAccumulate Reduce<TSource, TAccumulate>(IEnumerable<TSource> source, TAccumulate seed, Func<TAccumulate, TSource, TAccumulate> reducer)
    {
        TAccumulate result = seed;
        foreach (var item in source)
            result = reducer(result, item);
        return result;
    }
}

// 使用
var numbers = new List<int> { 1, 2, 3, 4, 5, 6 };
var filtered = MyFunctions.Filter(numbers, n => n % 2 == 0);
var mapped = MyFunctions.Map(filtered, n => n * n);
int sum = MyFunctions.Reduce(mapped, 0, (acc, n) => acc + n);
Console.WriteLine(sum); // 56

总结

  • 不使用 LINQ 时,可以通过循环 + 委托完全实现 mapfilterreduce
  • 自定义扩展方法可以保留链式调用的优雅性,且不依赖 System.Linq
  • 手动实现的好处是更清晰地理解内部机制,且在某些受限环境(如不允许引用 LINQ 的程序集)中仍然可用。

实际开发中,如果项目允许,推荐直接使用 LINQ,因为它更简洁、可读性更高且经过了高度优化。但在需要精确控制或学习原理时,自己实现也是很好的练习。

相关推荐
如果'\'真能转义说9 小时前
OOXML 文档格式剖析:哈希、ZIP结构与识别
xml·算法·c#·哈希算法
我是唐青枫9 小时前
终于不用手搓两级缓存了!C#.NET HybridCache 详解:L1 L2、标签失效与防击穿实战
redis·缓存·c#·.net
CHANG_THE_WORLD14 小时前
C语言中的 %*s 和 %.*s 和C++的字符串格式化输出
c语言·c++·c#
zxbmmmmmmmmm20 小时前
在 Avalonia 中编写高性能动画
c#·xaml·avalonia·compositon
加号31 天前
【C#】 HTTP 请求通讯实现指南
开发语言·http·c#
步步为营DotNet1 天前
.NET 11 中 Microsoft.Extensions.AI 在智能后端推理与决策优化的应用
云原生·c#·.net
工程师0071 天前
.NET 线程池 工作线程 扩容 + 空闲 + 回收 原理
c#·线程池·扩容·回收·空闲
njsgcs1 天前
c# solidworks createline 拉伸发现有微小两点间隙 导致拉伸变成薄壁特征 改bug画了6个小时 解决结果
c#·bug·solidworks
时光追逐者1 天前
一款基于 C# 开发的 Windows 10/11 系统增强工具,精简、优化、定制一站完成!
开发语言·windows·c#·.net