给定一个集合,我需要一次遍历所有元素三(或其他一些数量)。例如:
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而不是数组,我怎么能有效地重现这个?
答案 0 :(得分:9)
有效的方法是使用扩展方法:
public static IEnumerable<IList<T>> ChunksOf<T>(this IEnumerable<T> sequence, int size)
{
List<T> chunk = new List<T>(size);
foreach (T element in sequence)
{
chunk.Add(element);
if (chunk.Count == size)
{
yield return chunk;
chunk = new List<T>(size);
}
}
}
您可以像这样使用它:
foreach (IList<string> 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;
。
答案 1 :(得分:4)
此代码段将您的数组分组为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的倍数。
答案 2 :(得分:1)
虽然我更喜欢迈克尔的方法,但如果你需要特定领域的解析(例如DOB解析),你可能更喜欢更具体的东西
public static IEnumerable<User> ExtractUsers(IEnumerable<string> 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++;
}
}
答案 3 :(得分:0)
Take()
和Skip()
会做你想要的,但我会建议你避免使用这样的数组。您最好使用Person
,FirstName
和LastName
属性创建DateOfBirth
课程并保留其中的数组。
答案 4 :(得分:0)
如何忘记foreach,花哨的linq东西,临时的子列表等,并回到根源? : - )
调用.GetEnumerator()并在迭代中调用.MoveNext()三次。这就是枚举的核心。
以前的答案对我来说似乎过于复杂。这很简单和硬核: - )。
答案 5 :(得分:0)
您可以使用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]);