4

値のリストがあります:

IList<V> values = { V1, V2, V3, V4, V5, V6, V7 };

リストをリストのリストに変換したいと思います。各サブリストは指定されたサイズです。各サブリストのサイズは異なる場合があります。例えば:

IList<IList<V>> values_size2 = { { V1, V2 }, { V3, V4 }, { V5, V6 }, { V7 } };
IList<IList<V>> values_size3 = { { V1, V2, V3 }, { V4, V5, V6 }, { V7 } };
IList<IList<V>> values_size4 = { { V1, V2, V3, V4 }, { V5, V6, V7 } };

ネストされたループを使用すると、おそらくこれを非常に簡単に行うことができますが、LINQ を使用してこれを行う賢い方法があるかどうか疑問に思っていましたか?

Aggregateメソッドを使用することを最初に考えましたが、すぐには思い浮かびません。

ありがとう。

4

4 に答える 4

6

これはジェネリックIEnumerableベースのBatch関数です。戻り値の型を からIEnumerable<IEnumerable<T>>に変更するだけIEnumerable<IList<T>>で他に変更はありません (私の実装では既にリストになっているためです。リストのリストを返すように全体を変更するには、結果に対して `ToList を呼び出すか、より複雑なリファクタリング。

技術的には、これは LINQ を使用していないことに注意してください。LINQ で一般的に使用されるのと同じスタイルとパターンを使用する新しいメソッドを作成しているだけです。

public static IEnumerable<IEnumerable<T>> Batch<T>(this IEnumerable<T> source
    , int batchSize)
{
    //TODO validate parameters

    List<T> buffer = new List<T>();

    foreach (T item in source)
    {
        buffer.Add(item);

        if (buffer.Count >= batchSize)
        {
            yield return buffer;
            buffer = new List<T>();
        }
    }
    if (buffer.Count >= 0)
    {
        yield return buffer;
    }
}
于 2012-12-12T17:51:06.503 に答える
5

MoreLINQ Batch 拡張機能 ( Nugetから入手可能)を使用できます。

IList<IList<V>> values_size2 = values.Batch(2);
IList<IList<V>> values_size3 = values.Batch(3);
IList<IList<V>> values_size4 = values.Batch(4);

また、ここでソースを表示できます。

于 2012-12-12T17:51:50.193 に答える
1
 public static IEnumerable<IEnumerable<T>> Chunks<T>(this IEnumerable<T> source, int chunkSize)
 {
     while (source.Any())
     {
         yield return source.Take(chunkSize);
         source = source.Skip(chunkSize);
     }
 }
于 2016-08-18T18:27:56.493 に答える