以下代码显示了我想要做的事情:
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 };
}
如果没有适当的实现,我只使用像那样的自定义实现。有没有办法对标准框架做同样的事情?
答案 0 :(得分:3)
使用标准框架没有传统的方法。不过,我的解决方案确实存在一些问题。
ElementAt(i)
的使用非常低效,可能导致that
集合被多次迭代。这可能会导致性能问题Count
的使用也可能代价高昂,因为它可能导致that
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);
}
}
答案 1 :(得分:3)
您可以使用SequenceEqual,“如果您正在处理有序集合http://msdn.microsoft.com/en-us/library/bb348567.aspx
,则通过使用类型的默认相等比较器来比较元素,确定两个序列是否相等”否则collection1.Intersect(collection2).Count()== collection1.Count
会做的伎俩
答案 2 :(得分:0)
可以在链式声明中进行。我不确定我是否会建议这样的代码!
public static IEnumerable<IEnumerable<T>> DoIt<T>(this IEnumerable<T> that) {
return that.Zip(that.Skip(1), (a, b) => a.Equals(b) ? 1 : 0)
.Aggregate(
(IEnumerable<int>)new []{1, 0},
(c, x) => (new []{c.First() + 1}).Concat(c.Skip(x)),
_ => _.Zip(_.Skip(1), (to, skip) => new {skip, take = to - skip}))
.Reverse()
.Select(_ => that.Skip(_.skip).Take(_.take));
}
答案 3 :(得分:-2)
使用Any()扩展方法