Đây giống như câu trả lời được chấp nhận, nhưng một cách biểu diễn đơn giản hơn nhiều:
public static IEnumerable<IEnumerable<T>> Split<T>(this IEnumerable<T> items,
int numOfParts)
{
int i = 0;
return items.GroupBy(x => i++ % numOfParts);
}
Phương pháp trên chia một IEnumerable<T>
thành N số khối có kích thước bằng nhau hoặc gần bằng kích thước bằng nhau.
public static IEnumerable<IEnumerable<T>> Partition<T>(this IEnumerable<T> items,
int partitionSize)
{
int i = 0;
return items.GroupBy(x => i++ / partitionSize).ToArray();
}
Phương pháp trên chia một IEnumerable<T>
phần thành các phần có kích thước cố định mong muốn với tổng số phần là không quan trọng - đó không phải là câu hỏi.
Vấn đề với Split
phương pháp, bên cạnh việc chậm hơn, là nó xáo trộn đầu ra theo nghĩa là việc nhóm sẽ được thực hiện trên cơ sở bội số thứ của N cho mỗi vị trí, hay nói cách khác là bạn không nhận được các phần theo thứ tự ban đầu.
Hầu hết mọi câu trả lời ở đây hoặc không duy trì thứ tự, hoặc về phân vùng và không tách, hoặc rõ ràng là sai. Hãy thử cách này nhanh hơn, giữ được thứ tự nhưng dài dòng hơn:
public static IEnumerable<IEnumerable<T>> Split<T>(this ICollection<T> items,
int numberOfChunks)
{
if (numberOfChunks <= 0 || numberOfChunks > items.Count)
throw new ArgumentOutOfRangeException("numberOfChunks");
int sizePerPacket = items.Count / numberOfChunks;
int extra = items.Count % numberOfChunks;
for (int i = 0; i < numberOfChunks - extra; i++)
yield return items.Skip(i * sizePerPacket).Take(sizePerPacket);
int alreadyReturnedCount = (numberOfChunks - extra) * sizePerPacket;
int toReturnCount = extra == 0 ? 0 : (items.Count - numberOfChunks) / extra + 1;
for (int i = 0; i < extra; i++)
yield return items.Skip(alreadyReturnedCount + i * toReturnCount).Take(toReturnCount);
}
Phương pháp tương đương cho một Partition
hoạt động ở đây