我再次问这个问题,因为我上一次问它,它被错误地标记为重复.我这次将包含更多信息,这可能使我更容易理解我的需要(由于没有正确定义问题,这可能是我自己的错).
我正在尝试将通用类型的列表拆分为4个列表.为了简单和理解,我将在这个例子中使用一个整数列表,但这不应该有所作为.
我做了很多搜索,发现了多个答案,比如"使用LINQ将列表拆分为子列表",使用批处理方法进行拆分,我尝试了MoreLinq的Batch方法等等.这些建议适用于他们应该做的事情,但它们并不像我需要的那样工作.
如果我有一个包含以下元素的列表(整数范围1-25):
[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25]
Run Code Online (Sandbox Code Playgroud)
然后我需要做的是制作4个列表,其中包含可变数量的元素,其中元素在同一列表中递增,而不是跳转到下一个列表与下一个元素.
[ 1, 2, 3, 4, 5, 6, 7]
[ 8, 9, 10, 11, 12, 13, 14]
[15, 16, 17, 18, 19, 20, 21]
[20, 21, 22, 23, 24, 25]
Run Code Online (Sandbox Code Playgroud)
当在链接的任何一个问题中使用解决方案时,以4"部分"作为参数,我得到这样的列表(这是元素跳转到下一个列表而不是列表的下一个元素的示例):
[1, 5, 9, 13, 17, 21, 25],
[2, 6, 10, 14, 18, 22, 26],
[3, 7, 11, 15, 19, 23, 27],
[4, 8, 12, 16, 20, 24]
Run Code Online (Sandbox Code Playgroud)
或者这个(和MoreLinq的Batch方法一样)
[ 1, 2, 3, 4],
[ 5, 6, 7, 8],
[ 9, 10, 11, 12],
[13, 14, 15, 16],
[17, 18, 19, 20],
[21, 22, 23, 24],
[25, 26, 27],
Run Code Online (Sandbox Code Playgroud)
因此,第一个解决方案将列表拆分为4个列表,但是将元素放入错误的顺序.第二种解决方案按正确的顺序拆分列表,但不是正确的长度.在最后一个解决方案中,他获得了X个列表,每个列表中包含4个元素,其中我需要有4个列表,每个列表中包含X个元素.
您可以使用以下扩展方法在所需数量的子列表上拆分列表,并在第一个子列表中包含其他项:
public static IEnumerable<List<T>> Split<T>(this List<T> source, int count)
{
int rangeSize = source.Count / count;
int firstRangeSize = rangeSize + source.Count % count;
int index = 0;
yield return source.GetRange(index, firstRangeSize);
index += firstRangeSize;
while (index < source.Count)
{
yield return source.GetRange(index, rangeSize);
index += rangeSize;
}
}
Run Code Online (Sandbox Code Playgroud)
给定输入
var list = Enumerable.Range(1, 25).ToList();
var result = list.Split(4);
Run Code Online (Sandbox Code Playgroud)
结果是
[
[ 1, 2, 3, 4, 5, 6, 7 ],
[ 8, 9, 10, 11, 12, 13 ],
[ 14, 15, 16, 17, 18, 19 ],
[ 20, 21, 22, 23, 24, 25 ]
]
Run Code Online (Sandbox Code Playgroud)
更新:此解决方案为每个范围添加了额外的项目
public static IEnumerable<List<T>> Split<T>(this List<T> source, int count)
{
int rangeSize = source.Count / count;
int additionalItems = source.Count % count;
int index = 0;
while (index < source.Count)
{
int currentRangeSize = rangeSize + ((additionalItems > 0) ? 1 : 0);
yield return source.GetRange(index, currentRangeSize);
index += currentRangeSize;
additionalItems--;
}
}
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
3100 次 |
最近记录: |