使用 foreach 迭代时如何知道行索引?

Posted

技术标签:

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

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

foreach (DataRow temprow in temptable.Rows)

//this.text = temprow.INDEX????

【问题讨论】:

(C#) Get index of current foreach iteration的可能重复 【参考方案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();

希望对你有帮助

【讨论】:

以上是关于使用 foreach 迭代时如何知道行索引?的主要内容,如果未能解决你的问题,请参考以下文章

Java For each 如何获取索引

集合foreach迭代时,边迭代边删除,只能使用迭代器删除,不能使用集合删除,否则会导致并发修改异常for-each和Iterator的选择

如何获取每个 Kotlin 的当前索引

增强for循环(foreach)的坑

如何在刀片foreach循环中获取迭代次数

[JavaScript]_[初级]_[关于forin或for...in循环语句的用法]