LINQ对IEnumerable上重叠元素的操作

时间:2013-02-19 08:14:32

标签: c# algorithm linq

让我们考虑IEnumerable以及采用成对重叠索引的算法,例如{0,1},{1,2},{2,3}等结束基于这些索引的值创建新集合,例如{collection [0],collection [1] => result [0]},{collection [1],collection [2] =>结果[1]}等等。以下是直接实现的示例:

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

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

3 个答案:

答案 0 :(得分: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) 
                        });

答案 1 :(得分:2)

这是另一个:

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

这样你就可以获得对{0,1},{1,2} ......

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

答案 2 :(得分:2)

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();