Linq to Objects - 从数字列表中返回数字对

问题描述:

var nums = new[]{ 1, 2, 3, 4, 5, 6, 7};
var pairs  = /* some linq magic here*/ ;

=>对 = { {1, 2}, {3, 4}, {5, 6}, {7, 0} }

=> pairs = { {1, 2}, {3, 4}, {5, 6}, {7, 0} }

pairs 的元素应该是双元素列表,或者是一些具有两个字段的匿名类的实例,例如 new {First = 1, Second = 2}.

The elements of pairs should be either two-element lists, or instances of some anonymous class with two fields, something like new {First = 1, Second = 2}.

没有任何默认的 linq 方法可以通过单次扫描延迟完成此操作.用自身压缩序列会进行 2 次扫描,并且分组并不完全是懒惰的.最好的办法是直接实施它:

None of the default linq methods can do this lazily and with a single scan. Zipping the sequence with itself does 2 scans and grouping is not entirely lazy. Your best bet is to implement it directly:

public static IEnumerable<T[]> Partition<T>(this IEnumerable<T> sequence, int partitionSize) {
    Contract.Requires(sequence != null)
    Contract.Requires(partitionSize > 0)

    var buffer = new T[partitionSize];
    var n = 0;
    foreach (var item in sequence) {
        buffer[n] = item;
        n += 1;
        if (n == partitionSize) {
            yield return buffer;
            buffer = new T[partitionSize];
            n = 0;
        }
    }
    //partial leftovers
    if (n > 0) yield return buffer;
}