C# 循环遍历未知维度的数组
Posted
技术标签:
【中文标题】C# 循环遍历未知维度的数组【英文标题】:C# loop over an array of unknown dimensions 【发布时间】:2019-01-20 18:45:39 【问题描述】:我想创建一个扩展方法来循环 System.Array
未知数量的维度
目前我使用的是一种幼稚的方法:
public static void ForEach<T>(this Array source, Action<T> action)
if(source.Rank == 1)
for (int w = 0; w < source.GetLength(0); w++)
action((T)source.GetValue(w));
else if(source.Rank == 2)
for (int h = 0; h < source.GetLength(1); h++)
for (int w = 0; w < source.GetLength(0); w++)
action((T)source.GetValue(h, w));
else if(source.Rank == 3)
// etc
我敢肯定,还有更优雅的方法可以做到这一点。但我想不通。如何将这种方法推广到无限数量的维度?
【问题讨论】:
Why do C# multidimensional arrays not implement IEnumerable<T>?的可能重复 @ChristianGollhardt 在 OOP 语言中使用多维数组有什么“根本错误”?您希望如何在没有多维数组的情况下进行张量操作? 看来我误解了你的问题。我把尺寸误认为是尺寸的大小。 @koryakinp 【参考方案1】:您可以尝试递归方法,测试数组中的项目本身是否为数组。如果项目是可迭代的,则将调用 for 循环逻辑,否则您可以对项目进行任何您需要做的操作。如果您的对象实现了 ICollection,这应该相当简单。
【讨论】:
我认为 zcleghern 的意思类似于 ``` public static void ForEach如果您不关心索引,则可以在完全不知道其排名的情况下迭代 System.Array
。枚举器将命中每个元素。
public class Program
public static void IterateOverArray(System.Array a)
foreach (var i in a)
Console.WriteLine(i);
public static void Main()
var tests = new System.Array []
new int[] 1,2,3,4,5,6,7,8,
new int[,]
1,2,3,4,5,6,7,8
,
new int[,,]
1,2,3,4 ,
5,6,7,8
;
foreach (var t in tests)
Console.WriteLine("Dumping array with rank 0 to console.", t.Rank);
IterateOverArray(t);
输出:
Dumping array with rank 1 to console.
1
2
3
4
5
6
7
8
Dumping array with rank 2 to console.
1
2
3
4
5
6
7
8
Dumping array with rank 3 to console.
1
2
3
4
5
6
7
8
Link to DotNetFiddle example
【讨论】:
【参考方案3】:对于那些在家玩的人来说,这有点乱,但可以让你利用yield
超过一个等级foreach
public static IEnumerable<T> GetRank<T>(this Array source,int dimension, params int[] indexes )
var indexList = indexes.ToList();
indexList.Insert(dimension, 0);
indexes = indexList.ToArray();
for (var i = 0; i < source.GetLength(dimension); i++)
indexes[dimension] = i;
yield return (T)source.GetValue(indexes);
用法
var test1 = new int[2, 2, 3];
test1[1, 1, 0] = 1;
test1[1, 1, 1] = 2;
test1[1, 1, 2] = 3;
foreach (var item in test1.GetRank<int>(2,1,1))
Console.WriteLine(item);
输出
1
2
3
Full demo here
【讨论】:
以上是关于C# 循环遍历未知维度的数组的主要内容,如果未能解决你的问题,请参考以下文章
c#用foreach遍历数组、列表时是直接获得数据元素,而foreach哈希表时,为啥获得的是命名空间名??