通过2D数组进行映射

时间:2016-07-19 15:11:14

标签: c# functional-programming

我遇到了一个问题,我不确定我是否遗漏了某些内容,或者它是否真的在C#中笨拙。

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

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

更复杂。
from cell in matrix
select f(cell)

或等效的matrix.Select(f)

我忍不住认为我不能成为第一个想要这样做的人,所以我想知道是否有类似内置的东西,或者我最好只是为2D编写自己的LINQ扩展阵列

2 个答案:

答案 0 :(得分:0)

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

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

答案 1 :(得分:0)

不确定这是否是“最佳”方式(无论这意味着什么),但这至少起作用。如果您需要更多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);
}