.NET一次迭代IEnumerable中的几个元素
给定一个集合,我需要一次遍历所有元素三(或其他一些数量)。 例如:
string[] exampleData = {"John", "Doe", "1.1.1990", "Jane", "Roe", "2.2.1980"} for(int i = 0; i < exampleData.Length; i += 3) { CreateUser(foreName: exampleData[i], surName: exampleData[i+1], dateOfBirth: exampleData[i+2]); }
如果exampleData是IEnumerable而不是数组,我怎么能有效地重现这个?
一种有效的方法是使用扩展方法:
public static IEnumerable> ChunksOf(this IEnumerable sequence, int size) { List chunk = new List (size); foreach (T element in sequence) { chunk.Add(element); if (chunk.Count == size) { yield return chunk; chunk = new List (size); } } }
你可以像这样使用它:
foreach (IList chunk in exampleData.ChunksOf(3)) { CreateUser(foreName: chunk[0], surName: chunk[1], dateOfBirth: chunk[2]); }
请注意,如果sequence.Count()
不是size
的整数倍,则ChunksOf
会丢弃最后一个部分块。 如果你想要返回一个部分块,你可以添加到结尾: if (chunk.Count > 0) yield return chunk;
。
此代码段将您的数组分组为3个元素的集合,然后为每个集合创建一个用户。
exampleData.Select((elem, index) => new {elem, index}) .GroupBy(x => x.index/3) .Select(x => CreateUser( x.ElementAt(0).elem, x.ElementAt(1).elem, x.ElementAt(2).elem));
当然,您需要确保数组的长度是3的倍数。
虽然我更喜欢Michael的方法,但是如果你需要特定于字段的解析(例如DOB解析),你可能更喜欢更具体的东西。
public static IEnumerable ExtractUsers(IEnumerable input) { int i = 0; string forename; string surname; string dateofbirth; foreach (string current in input) { switch (i) { case 0: one = forename; break; case 1: two = surname; break; case 2: three = dateofbirth; i = -1; //uck, this will get incremented at the bottom yield return CreateUser(forename, surname, dateofbirth); break; } i++; } }
Take()
和Skip()
会做你想要的,但我会建议你避免使用这样的数组。 你最好用FirstName
, LastName
和DateOfBirth
属性创建一个Person
类,并保留一组数组。
如何忘记foreach,花哨的linq东西,临时的子列表等,并回到根源? 🙂
调用.GetEnumerator()并在迭代中调用.MoveNext()三次。 这就是枚举的核心。
以前的答案对我来说似乎过于复杂。 这很简单和硬核:-)。
您可以使用LINQ
string[] exampleData = {"John", "Doe", "1.1.1990", "Jane", "Roe", "2.2.1980"}; int chunkSize = 3; var seqences = from seqIndex in Enumerable.Range(0, exampleData.Length) group exampleData[seqIndex] by seqIndex / chunkSize; foreach (var sub in seqences) { CreateUser(sub.ToList()[0], sub.ToList()[1], sub.ToList()[2]); }
编辑:
var seqences = from m in Enumerable.Range(0, exampleData.Count()) group exampleData.ToList()[m] by m / chunkSize;
要么
int chunkSize = 3; var seqences = Enumerable.Range(0, exampleData.Count()) .GroupBy(m => m/chunkSize, m => exampleData.ToList()[m]);