下面的代码展示了我想要做什么:
public static IEnumerable<IEnumerable<T>> DoIt<T>(this IEnumerable<T> that)
{
if (that == null)
throw new ArgumentNullException();
if (that.Count() > 1)
{
var result = new Collection<IEnumerable<T>>();
var collection = new Collection<T>();
collection.Add(that.ElementAt(0));
for (int i = 1; i < that.Count(); ++i)
{
if (!that.ElementAt(i).Equals(that.ElementAt(i - 1)))
{
result.Add(collection);
collection = new Collection<T>();
}
collection.Add(that.ElementAt(i));
}
result.Add(collection);
return result;
}
return new Collection<IEnumerable<T>>() { that };
}
如果没有合适的实现,我只会使用像那个那样的自定义实现。有什么方法可以用标准框架做同样的事情吗?
请您参考如下方法:
使用标准框架没有传统方法可以做到这一点。不过,您的解决方案确实存在一些问题。
ElementAt(i)的使用效率非常低,并且会导致that集合被迭代很多很多次。这可能会导致性能问题Count的使用也可能代价高昂,因为它可能导致that的完整枚举- 与大多数 LINQ 方法不同,它不使用延迟执行。要解决此问题,您需要使用
yield return样式的解决方案。
这里有一个替代方案
public static IEnumerable<IEnumerable<T>> DoIt<T>(this IEnumerable<T> that) {
using (var e = that.GetEnumerator()) {
if (!e.MoveNext()) {
yield break;
}
bool hasMore;
do {
var item = e.Current;
var list = new List<T>();
list.Add(item);
hasMore = e.MoveNext();
while (hasMore && item.Equals(e.Current)) {
list.Add(e.Current);
hasMore = e.MoveNext();
}
yield return list;
} while (hasMore);
}
}
