我有一个IEnumerable<string>我想分成三组,所以如果我的输入有6个项目,我会得到一个IEnumerable<IEnumerable<string>>返回的两个项目,每个项目将包含IEnumerable<string>我的字符串内容.
我正在寻找如何使用Linq而不是简单的for循环
谢谢
Meh*_*ari 30
var result = sequence.Select((s, i) => new { Value = s, Index = i })
.GroupBy(item => item.Index / 3, item => item.Value);
Run Code Online (Sandbox Code Playgroud)
请注意,这将返回一个IEnumerable<IGrouping<int,string>>功能类似于您想要的功能.但是,如果您严格需要将其键入IEnumerable<IEnumerable<string>>(要传递给C#3.0中不支持泛型差异的方法),您应该使用Enumerable.Cast:
var result = sequence.Select((s, i) => new { Value = s, Index = i })
.GroupBy(item => item.Index / 3, item => item.Value)
.Cast<IEnumerable<string>>();
Run Code Online (Sandbox Code Playgroud)
Mat*_*son 29
这是对此线程的迟回复,但这是一个不使用任何临时存储的方法:
public static class EnumerableExt
{
public static IEnumerable<IEnumerable<T>> Partition<T>(this IEnumerable<T> input, int blockSize)
{
var enumerator = input.GetEnumerator();
while (enumerator.MoveNext())
{
yield return nextPartition(enumerator, blockSize);
}
}
private static IEnumerable<T> nextPartition<T>(IEnumerator<T> enumerator, int blockSize)
{
do
{
yield return enumerator.Current;
}
while (--blockSize > 0 && enumerator.MoveNext());
}
}
Run Code Online (Sandbox Code Playgroud)
还有一些测试代码:
class Program
{
static void Main(string[] args)
{
var someNumbers = Enumerable.Range(0, 10000);
foreach (var block in someNumbers.Partition(100))
{
Console.WriteLine("\nStart of block.");
foreach (int number in block)
{
Console.Write(number);
Console.Write(" ");
}
}
Console.WriteLine("\nDone.");
Console.ReadLine();
}
}
Run Code Online (Sandbox Code Playgroud)
dic*_*d30 21
我知道这已经得到了回答,但是如果你打算经常采用IEnumerables的片段,那么我建议像这样制作一个通用的扩展方法:
public static IEnumerable<IEnumerable<T>> Split<T>(this IEnumerable<T> source, int chunkSize)
{
return source.Where((x,i) => i % chunkSize == 0).Select((x,i) => source.Skip(i * chunkSize).Take(chunkSize));
}
Run Code Online (Sandbox Code Playgroud)
然后你可以sequence.Split(3)用来得到你想要的东西.
(你可以把它命名为'slice'或'chunk',如果你不喜欢'split'已经为字符串定义了.'Split'正是我碰巧称之为我的.)
Arn*_*sen 15
灵感来自@ dicegiuy30的实现,我想创建一个只迭代源一次并且不在内存中构建整个结果集来补偿的版本.我想出的最好的是:
public static IEnumerable<IEnumerable<T>> Split2<T>(this IEnumerable<T> source, int chunkSize) {
var chunk = new List<T>(chunkSize);
foreach(var x in source) {
chunk.Add(x);
if(chunk.Count <= chunkSize) {
continue;
}
yield return chunk;
chunk = new List<T>(chunkSize);
}
if(chunk.Any()) {
yield return chunk;
}
}
Run Code Online (Sandbox Code Playgroud)
这样我就可以按需构建每个块.我希望我也应该尽可能地避免这种情况List<T>,但也没有想到这一点.
| 归档时间: |
|
| 查看次数: |
21290 次 |
| 最近记录: |