LINQ对IEnumerable上重叠元素的操作

本文关键字:元素 操作 重叠 IEnumerable LINQ | 更新日期: 2023-09-27 17:59:57

让我们考虑一个IEnumerable和采用成对重叠索引(例如{0,1}、{1,2}、{2,3}等)的算法。end根据这些索引的值创建一个新集合,例如{collection[0]、collection[1]=>result[0]}、}collection[1]、collection[2]=>result[1]}等。下面是直接实现的示例:

IEnumerable<string> collection = new string[100];
var array = collection.ToArray();
var results = array.Skip(1).Select((e, i) => e - array[i]);

如何以更好的方式实现目标?

LINQ对IEnumerable上重叠元素的操作

var array = new string[] { "one", "two", "three" };
var result = Enumerable.Range(1, array.Length - 1)
                        .Select(i => new[] { array[i - 1], array[i] });

这里是@TrustMe解决方案,使用数组而不是元组(只是为了向您展示示例,您不应该接受我的答案):

IEnumerable<string> collection = new string[] { "one", "two", "three" };
var result = collection.Zip(collection.Skip(1), (x,y) => new [] { x, y });

但请记住,如果不使用按索引访问(使用数组或列表),则该集合将被枚举两次。


UPDATE这里有一个扩展方法,它将与集合一起工作,并且将只枚举序列一次

public static class Extensions
{
    public static IEnumerable<T[]> GetOverlappingPairs<T>(
        this IEnumerable<T> source)
    {
        var enumerator = source.GetEnumerator();
        enumerator.MoveNext();
        var first = enumerator.Current;
        while (enumerator.MoveNext())
        {
            var second = enumerator.Current;
            yield return new T[] { first, second };
            first = second;
        }
    }
}

用法:

var result = collection.GetOverlappingPairs();

还有一个:

var ints = Enumerable.Range(0, 10);
var paired = ints.Zip(ints.Skip(1), Tuple.Create);

这样你就会得到{0,1},{1,2}对。。。

我想这就是您所要求的,因为您的代码示例与您所描述的有点不同…:)

 var result = Enumerable.Range(1, arrayCollection.Length - 1)
               .Select(i => new[] {arrayCollection[i - 1], arrayCollection[i]});

如果arrayCollectionIEnumerable

var result = Enumerable.Range(1, arrayCollection.Count() - 1)
                 .Select(i => new[] {
                          arrayCollection.ElementAt(i - 1), 
                          arrayCollection.ElementAt(i) 
                        });