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]);
如何以更好的方式实现目标?
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]});
如果arrayCollection
是IEnumerable
var result = Enumerable.Range(1, arrayCollection.Count() - 1)
.Select(i => new[] {
arrayCollection.ElementAt(i - 1),
arrayCollection.ElementAt(i)
});