我有这个基于锯齿状数组的循环,我需要在不同的地方多次使用它。
我怎样才能防止自己一次又一次地重写这个循环,以便我会复制它?
foreach (int[] columns in rowsAndColumns)
{
foreach (int element in columns)
{
}
}
我有这个基于锯齿状数组的循环,我需要在不同的地方多次使用它。
我怎样才能防止自己一次又一次地重写这个循环,以便我会复制它?
foreach (int[] columns in rowsAndColumns)
{
foreach (int element in columns)
{
}
}
你可以写
foreach (int element in rowsAndColumns.SelectMany(col => col))
{
// ...
}
反而。如果您不想一直键入它,可以将其抽象为辅助方法:
foreach (int element in rowsAndColumns.Flatten())
{
// ...
}
// [...]
public IEnumerable<T> Flatten(this IEnumerable<IEnumerable<T>> source)
{
return source.SelectMany(e => e);
}
这取决于你想做什么,但如果你想对每个 int 执行一个操作,你可以选择下面的扩展。一些空值检查可能是可取的。
static class RowColExtension
{
public static void Each(this int[][] rowCols, Action<int> a)
{
foreach (var r in rowCols)
{
foreach (var c in r)
{
a(c);
}
}
}
}
这取决于你想在循环中做什么。我会这样处理它(未经测试的代码在我脑海中!):
public static class MyHelper {
public static void ForEach(this IEnumerable<int[]> rowsAndColumns, Action<int> action) {
foreach (int[] columns in rowsAndColumns) {
foreach (int element in columns) {
action(element);
}
}
}
}
现在你可以这样称呼它:
rowsAndColumns.ForEach(e => Console.WriteLine(e));
扩展方法:
// It's late and I'm tired, the array declaration might be off.
public static void Visit(this int[][] array, Action<int> visitor)
{
foreach (int[] columns in array)
{
foreach (int element in columns)
{
visitor(element);
}
}
}
myArray.Visit(elem => Console.WriteLine(elem));
您也可以使用Action<int,int>
来获取行。
由于您在不考虑行或列的情况下迭代所有元素,因此您应该将锯齿状数组转换为第一类数据结构并IEnumerable
使用foreach
. 相同的一级数据结构可以支持单参数和双参数索引器、范围检查等。
编辑:
这是一种使用抽象而不是操作低级数据结构的方法。这假设锯齿状数组已分配到其他地方。无论哪种方式,关键是我们现在可以foreach
直接在数据结构上使用:
public class JaggedArray : IEnumerable<int>
{
private int[][] array;
public JaggedArray(int[][] array)
{
this.array = array;
}
public int this[int row, int column]
{
get { return array[row][column]; }
set { array[row][column] = value; }
}
public IEnumerable<int[]> Rows
{
get { return array; }
}
public IEnumerator<int> GetEnumerator()
{
foreach (var row in array)
foreach (var item in row)
yield return item;
}
System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator()
{
return GetEnumerator();
}
}