我遇到了一个问题,我不确定我是否遗漏了某些内容,或者它是否真的在C#中笨拙。
我有一个2D数组(Foo[,]
),我想要做的是将它映射到Bar[,]
,只使用Func<Foo, Bar>
。基本上,我想要的是T[,]
的任何给定T
的仿函数实例。
“显而易见”的方法当然是简单地从头开始构建一个新数组,迭代每个列的行和列,并手动将该函数应用于ever cell。我真的很想使用LINQ,因为没有任何理由这比
更复杂。from cell in matrix
select f(cell)
或等效的matrix.Select(f)
。
我忍不住认为我不能成为第一个想要这样做的人,所以我想知道是否有类似内置的东西,或者我最好只是为2D编写自己的LINQ扩展阵列
答案 0 :(得分:0)
.Net Framework中没有可直接使用2d数组的LINQ方法。您可以从内置代码中获得最佳效果 - 通过非通用IEnumerable
使用手动Cast
(Why 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);
}