The extension method from this answer does pretty much what you ask (Microsoft also provide an implementation to group contiguous items in a sequence):
public static IEnumerable<IGrouping<int, T>>
GroupConsecutive<T>(this IEnumerable<T> set, Func<T, T, bool> predicate)
{
var i = 0;
var k = 0;
var ranges = from e in set
let idx = ++i
let next = set.ElementAtOrDefault(idx)
let key = (predicate(e, next)) ? k : k++
group e by key into g
select g;
return ranges;
}
You could use it as follows:
void Main()
{
LinkedList<string> myList = new LinkedList<string>();
myList.AddLast("aaa");
myList.AddLast("aaa");
myList.AddLast("bbb");
myList.AddLast("bbb");
myList.AddLast("aaa");
myList.AddLast("aaa");
myList.AddLast("aaa");
IGrouping<int,string> ggg;
var groups=myList.GroupConsecutive((a,b)=>a==b);
ILookup<string,int> lookup=groups.ToLookup(g=>g.First(),g=>g.Count());
foreach(var x in lookup["aaa"])
{
Console.WriteLine(x); //outputs 2 then 3
}
foreach(var x in lookup["bbb"])
{
Console.WriteLine(x); //outputs 2
}
}
Notice that the final container is an ILookup which behaves a little like a Dictionary, but allows one to store multiple values against a single key.
与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…