是否可以从第一个使用foreach的元素开始进行迭代?


86

我正在考虑为我的自定义集合(一棵树)实现IEnumerable,以便可以使用foreach遍历我的树。但是据我所知,foreach总是从集合的第一个元素开始。我想从foreach从哪个元素开始。是否有可能以某种方式更改foreach的起始元素?



如果您不从第一个元素开始,那么如何定义迭代器的行为?到达序列末尾会发生什么?然后是否返回到第一个元素并遍历其余元素?
Dan J

@ChaosPandion的评论是我处理这些问题的地方。:)
Dan J

Answers:


162

是。请执行下列操作:

Collection<string> myCollection = new Collection<string>;

foreach (string curString in myCollection.Skip(3))
    //Dostuff

Skip是IEnumerable函数,可跳过从当前索引开始指定的许多内容。在另一方面,如果你想使用前三个你可以使用.Take

foreach (string curString in myCollection.Take(3))

这些甚至可以配对在一起,因此,如果您只想要4-6个项目,则可以执行以下操作:

foreach (string curString in myCollection.Skip(3).Take(3))

好决定。WTB自动完成(gahh记不清它的真实名称了);)
MoarCodePlz 2011年

这实际上是跳过还是仅创建副本?IE会将这两个不同:foreach(List<string> row in rows.skip(1)){ row[0] = "newInfo"; } vs for(int i=1; i<rows.Count;i++){ List<string> row = rows[i]; row[0] = "newStuff"; }
TigerBear

25

Skip为此,最容易使用LINQ to Objects中的方法来跳过给定数量的元素:

foreach (var value in sequence.Skip(1)) // Skips just one value
{
    ...
}

显然,只需将其他任何值更改为1即可跳过不同数量的元素...

同样,您可以Take用来限制返回的元素数。

您可以在我的Edulinq博客系列中阅读有关这两种方法(以及相关SkipWhileTakeWhile方法)的更多信息。


乔恩,如果“序列”为Null,这不会冒例外的危险吗?
WEFX

@WEFX:好吧,我们不知道是否sequence可以合法存在null。大概OP可以自己处理-这实际上不是问题的一部分...
Jon Skeet 2015年

5

您可以使用Enumerable.Skip跳过一些元素,然后从那里开始。

例如:

foreach(item in theTree.Skip(9))  // Skips the first 9 items
{
    // Do something

但是,如果您正在编写树,则可能需要在树项本身上提供一个成员,该成员将返回一个新成员,该成员IEnumerable<T>将从此处开始枚举。从长远来看,这可能会更加有用。


IEnumerable<T> SubTree(rootIndex)什么?好决定!
Dan J

感谢您的回答,skip看起来很有前途,阅读了有关skip的MSDN信息。我得出的结论是,也许可以编写StartFrom(此IEnumerable <MyTree>树,MyTreeElement元素)方法,该方法将是IEnumerable <MyTree>的扩展方法。会返回IEnumerable <MyTreeElement>,我应该从中开始进行迭代。然后,也许我可以将此方法用作foreach(tree.StartFrom(someElement)中的var元素))。
inferno

@inferno:是的,您可以轻松地做到这一点。但是,我只是将一个方法/属性添加到MyTreeElement中,该方法/属性更像是:IEnumerable<MyTreeElement> Children,因此您可以这样做: foreach(var item in someElement.Children)-比使用IMO扩展方法要清晰得多。
Reed Copsey

-1

Foreach将按照您的实现定义的方式遍历您的集合IEnumerable。因此,尽管您可以跳过元素(如上所述),但是从技术上讲,您仍然以相同的顺序遍历元素。

不确定要实现的目标,但是您的类可能具有多个IEnumerable属性,每个属性都按特定顺序枚举元素。


-1

如果要跳过阅读中的行DataGridView,请尝试以下操作

foreach (DataGridViewRow row in dataGridView1.Rows.Cast<DataGridViewRow().Skip(3))

如果要将一个内容复制DataGridView到另一个跳过的行,请尝试此操作,

foreach (DataGridViewRow row in dataGridView1.Rows.Cast<DataGridViewRow>().Skip(3))
{
    foreach (DataGridViewCell cell in row.Cells)
    {
        string value = cell.Value.ToString();
        dataGridView2.Rows[i].Cells[j].Value = cell.Value.ToString();
        j++;
    }
    i++;
    j = 0;
}

这会将内容从一个复制DataGridView到另一个,跳过3行。


这不能回答所提出的问题-该问题根本没有提到DataGridView(甚至没有UI框架)。
NightOwl888 '18

@ NightOwl888的答案是,因为问题是关于跳过一些迭代并在foreach循环中进行迭代。在我的示例中,我只是使用Skip()应用于DataGridView。
Juned Khan Momin
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.