【问题标题】:How can I know a row index while iterating with foreach?使用 foreach 迭代时如何知道行索引?
【发布时间】:2010-12-05 04:15:29
【问题描述】:

在下一个示例中,我如何知道当前行索引?

foreach (DataRow temprow in temptable.Rows)
{
//this.text = temprow.INDEX????
}

【问题讨论】:

标签: c# foreach


【解决方案1】:

你必须自己创建一个

var i = 0;
foreach (DataRow temprow in temptable.Rows)
{
    this.text = i;
    // etc
    i++;
}

或者你可以只做一个 for 循环。

【讨论】:

  • +1,尽管我很少(如果有的话)提倡for 而不是foreach。不同的存储机制在基于索引的查找(例如链表)上可能表现很差,而在直接枚举上表现很好。
  • @Adam 可以理解,测量可能是找出哪种方法更好的最好办法。
【解决方案2】:

我在 MiscUtil 中有一个类型可以帮助解决这个问题 - SmartEnumerable。这是一个愚蠢的名字,但它可以工作:) 有关详细信息,请参阅usage page,如果您使用的是 C# 3,您可以使其更简单:

foreach (var item in temptable.Rows.AsSmartEnumerable())
{
    int index = item.Index;
    DataRow value = item.Value;
    bool isFirst = item.IsFirst;
    bool isLast = item.IsLast;
}

【讨论】:

  • 我假设 temptable.Rows 是一个 DataTable,但是当我尝试执行您在这段代码中显示的操作时,它告诉我:DataRowCollection“不包含 AsSmartEnumerable 的定义”。那么temptable.Rows是一个什么样的对象呢?帮助..
  • @J.Rodríguez 您是否在项目中包含了 MiscUtil,然后根据使用页面添加 using 指令?基本上它应该适用于任何IEnumerable<T>
  • 是的,乔恩,它包括在内。对于列表是否有效,我不知道为什么它不允许在DataTable 中使用它例如:List<string> list = new List<string>(); foreach (var item in list.AsSmartEnumerable())
  • 应该注意的是,我只使用了它的 MiscUtil:SmartEnumerable.csSmartEnumerableExt.cs。我还缺少其他东西?
  • @J.Rodríguez 我的猜测是 Rows 只实现了非泛型接口。使用 LINQ 调用 Cast,然后在结果上调用 AsSmartEnumerable。
【解决方案3】:

如果你可以使用Linq,你可以这样做:

foreach (var pair in temptable.Rows.Cast<DataRow>()
                                   .Select((r, i) => new {Row = r, Index = i}))
{
    int index = pair.Index;
    DataRow row = pair.Row;
}

【讨论】:

  • 伙计,我正要输入这个回复......哦,好吧
【解决方案4】:

你实际上没有。 foreach 的优点之一是你没有额外的代码处理增量和长度检查。

如果你想拥有自己的索引,你必须这样做

int rowindex = 0;
foreach (DataRow temprow in temptable.Rows)
{
//this.text = temprow.INDEX????
    this.text = rowindex++;
}

【讨论】:

    【解决方案5】:
    int rowIndex = temptable.Rows.IndexOf(temprow);
    

    【讨论】:

    • 我建议不要这样做。它可能比使用您自己的增量器花费更多。
    • 我在测试时在长时间运行的 foreach 循环中设置了一个断点,并在监视窗口中使用它来帮助确定我还需要多长时间。足以进行调试:)
    【解决方案6】:

    使用标准的 foreach 循环是不可能的。最简单的方法是使用 for 循环

    for ( int i = 0; i < temptable.Rows.Count; i++ ) {
      DataRow temprow = (DataRow)temptable.Rows[i];
      ...
    }
    

    另一种选择是使用扩展方法

    public static void ForEachIndex<T>(this IEnumerable<T> e, Action<T,int> del) {
      var i = 0; 
      foreach ( var cur in e ) {
        del(cur,i);
      }
    }
    

    ...

    temptable.Rows.Cast<DataRow>.ForEachIndex((cur,index) 
    {
      ...
    });
    

    【讨论】:

      【解决方案7】:

      嘿,我想有一个更快的方法。无需迭代! 首先,为 DataRow 的 Friend RowID 字段声明一个静态变量:

      Private Shared RowIDFieldInfo As System.Reflection.FieldInfo = GetType(DataRow).GetField("_rowID", System.Reflection.BindingFlags.NonPublic Or System.Reflection.BindingFlags.Instance)
      

      那么你需要做的就是使用它:

      RowIDFieldInfo.GetValue(MyDataRow) - 1
      

      我在使用或过滤后没有对此进行测试。 就我而言,我不需要这样做,所以这是可行的。

      【讨论】:

        【解决方案8】:

        迟到总比没有好...

        foreach (DataRow temprow in temptable.Rows)
        {
            temptable.Rows.IndexOf(temprow);
        }
        

        【讨论】:

          【解决方案9】:

          写入任意单元格编号并获取行索引


          foreach (var item in datagridview.Rows)
             {
               //TextBox1.Text= item.Cells[0].RowIndex.ToString();
             }
          

          【讨论】:

            【解决方案10】:

            要么使用for循环,要么使用整数跟随:

            int count =0;
            foreach (DataRow temprow in temptable.Rows)
            {
                //count is the index of the row in the array temptable.Rows
                //this.text = temprow.INDEX????
                ++count;
            }
            

            【讨论】:

              【解决方案11】:

              你可以使用标准的for循环来获取索引

              for(int i=0; i<temptable.Rows.Count; i++)
              {
                 var index = i;
                 var row = temptable.Rows[i];
              }
              

              【讨论】:

                【解决方案12】:

                虽然 LFSR 的答案是正确的,但我很确定在几乎任何集合/列表上调用 .IndexOf 都会枚举列表,直到找到匹配的行。对于大型 DataTable,这可能会很慢。

                for (i = 0; i

                【讨论】:

                  【解决方案13】:

                  使用索引而不是使用列名检索数据的替代方法

                  foreach (DataRow temprow in temptable.Rows)
                  {
                      String col1 = temprow[0].ToString().Trim();
                      String col2 = temprow[1].ToString().Trim();
                  }
                  

                  希望对你有帮助

                  【讨论】:

                    猜你喜欢
                    • 1970-01-01
                    • 1970-01-01
                    • 1970-01-01
                    • 1970-01-01
                    • 1970-01-01
                    • 2020-02-29
                    • 2021-11-05
                    • 2012-02-26
                    • 1970-01-01
                    相关资源
                    最近更新 更多