【问题标题】:How can I prevent duplication of a common loop in my solution?如何防止在我的解决方案中重复公共循环?
【发布时间】:2011-05-04 20:32:27
【问题描述】:

我有这个基于锯齿状数组的循环,我需要在不同的地方多次使用它。

我怎样才能防止自己一次又一次地重写这个循环,以便我会复制它?

      foreach (int[] columns in rowsAndColumns)
      {
          foreach (int element in columns)
          {

          }
      }

【问题讨论】:

    标签: c# .net code-duplication jagged-arrays


    【解决方案1】:

    你可以写

    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);
    }
    

    【讨论】:

    • 我再一次记得,我必须让自己更熟悉 SelectMany ;-)
    【解决方案2】:

    这取决于你想做什么,但如果你想对每个 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);
                }
            }
        }
    }
    

    【讨论】:

      【解决方案3】:

      这取决于你想在循环中做什么。我会这样处理它(未经测试的代码在我脑海中!):

      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));
      

      【讨论】:

        【解决方案4】:

        扩展方法:

        // 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&lt;int,int&gt; 来获取该行。

        【讨论】:

          【解决方案5】:

          由于您要遍历所有元素而不考虑行或列,因此您应该将锯齿状数组转换为一流的数据结构并实现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();
              }
          }
          

          【讨论】:

            猜你喜欢
            • 2021-11-20
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2021-04-22
            • 1970-01-01
            • 2017-02-27
            • 2021-03-15
            • 1970-01-01
            相关资源
            最近更新 更多