【问题标题】:Mapping over a 2D array映射二维数组
【发布时间】:2016-11-22 13:48:05
【问题描述】:

我遇到了一个问题,我不确定我是否遗漏了什么,或者它在 C# 中是否真的很笨重。

我有一个二维数组 (Foo[,]),我想做的是将它映射到 Bar[,],只使用 Func<Foo, Bar>。基本上,我想要的是任何给定T 的T[,] 函子实例。

“显而易见”的方法当然是简单地从头开始构建一个新数组,迭代每一列的行和列,然后手动将函数应用于每个单元格。不过,我真的很想为此使用 LINQ,因为没有任何理由这应该比

from cell in matrix
select f(cell)

或等效的matrix.Select(f)。

我不禁想到我不能成为第一个想要这样做的人,所以我想知道是否有类似的内置功能,或者我最好的选择是简单地为 2D 编写我自己的 LINQ 扩展数组?

【问题讨论】:

    标签: c# functional-programming


    【解决方案1】:

    不确定这是否是“最好”的方式(无论这意味着什么),但至少这可行。如果您需要更多 LINQ 语法,可以轻松扩展。

    public static class Matrix
    {
        public static TResult[,] Select<T, TResult>(this T[,] source, Func<T, TResult> f)
        {
            var rows = source.GetLength(0);
            var columns = source.GetLength(1);
            var result = new TResult[rows, columns];
    
            for (var row = 0; row < rows; row++)
            {
                for (var column = 0; column < columns; column++)
                {
                    result[row, column] = f(source[row, column]);
                }
            }
    
            return result;
        }
    }
    

    使用以下(相当乏味)xunit 事实进行测试,请随时指出错误。

    [Fact]
    public void MatrixSelect_GivenFunction_MapsMatrix()
    {
        var matrix = new[,]
        {
            {true, true},
            {false, true}
        };
    
        var transformed =
            from cell in matrix
            select cell ? 1 : 0;
    
        var expected = new[,]
        {
            {1, 1},
            {0, 1}
        };
        Assert.Equal(expected, transformed);
    }
    

    【讨论】:

      【解决方案2】:

      .Net Framework 中没有直接处理二维数组的 LINQ 方法。您可以从内置代码中获得最佳效果 - 通过非通用 IEnumerable 手动迭代所有项目 Cast (Why do C# Multidimensional arrays not implement IEnumerable<T>?, Using Linq with 2D array, Select not found)

      作为解决方案 - 编写您自己的扩展或查找库。

      【讨论】:

      • 编写一堆自定义 LINQ 扩展似乎是最简单、最干净的方法。必须编写和维护这种样板代码有点乏味,但是哦。
      猜你喜欢
      • 2018-06-10
      • 2011-01-10
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-11-21
      相关资源
      最近更新 更多