var a = new List<string>() {"aa","aa","bb","bb","bb","cc","aa","aa","cc","cc" };
我想找到所有字符串的出现次数,对于上面的列表,我希望输出如下:
Index String Count
0 aa 2
2 bb 3
5 cc 1
6 aa 2
8 cc 2
但是当我尝试groupby时,它给出的总计数不是位置。 我怎么能得到这个?
编辑:我希望列表中超过1000万个条目。
答案 0 :(得分:2)
您可以执行以下操作。
使用Linq的解决方案
var a = new List<string>() {"aa","aa","bb","bb","bb","cc","aa","aa","cc","cc" };
var result = Enumerable.Range(0, a.Count())
.Where(x => x == 0 || a[x - 1] != a[x])
.Select((x,index) => new Stat<string>
{
Index =index,
StringValue = a[x],
Count = a.Skip(x).TakeWhile(c => c == a[x]).Count()
});
其中Stat定义为
public class Stat<T>
{
public int Index{get;set;}
public T StringValue {get;set;}
public int Count {get;set;}
}
更新 使用迭代器
public IEnumerable<Stat<T>> CountOccurance<T>(IEnumerable<T> source)
{
var lastItem = source.First();
var count = 1;
var index= 0;
foreach(var item in source.Skip(1))
{
if(item.Equals(lastItem))
{
count++;
}
else
{
yield return new Stat<T>
{
Index = index,
StringValue = lastItem,
Count = count
};
count=1;
lastItem = item;
index++;
}
}
yield return new Stat<T>
{
Index = index,
StringValue = lastItem,
Count = count
};
}
然后您可以将结果提取为
var result = CountOccurance(a);
答案 1 :(得分:1)
如果您将多次使用此逻辑,则可以考虑编写自己的扩展方法。
public static class ExtensionMethods
{
public static IEnumerable<SpecialGroup<TKey>> GroupAccordingToSuccessiveItems<TSource, TKey>(this IEnumerable<TSource> source, Func<TSource, TKey> keySelector)
{
int index = 0;
int count = 0;
TKey latestKey = default(TKey);
foreach (var item in source)
{
TKey key = keySelector(item);
if (index != 0 && !object.Equals(key, latestKey))
{
yield return new SpecialGroup<TKey>
{
Index = index - count,
Obj = latestKey,
Count = count
};
count = 0;
}
latestKey = key;
count++;
index++;
}
yield return new SpecialGroup<TKey>
{
Index = index - count,
Obj = latestKey,
Count = count
};
}
}
public class SpecialGroup<T>
{
public int Index { get; set; }
public T Obj { get; set; }
public int Count { get; set; }
}
然后您可以调用它,
var result =
a.
GroupAccordingToSuccessiveItems(i => i);
这将迭代所有列表一次。