List<string> str = new List<string>() {
"Alpha", "Beta", "Alpha", "Alpha", "Gamma", "Beta", "XYZ" };
预期产出:
String | Indexes
----------------------------
Alpha | 0, 2, 3
Beta | 1, 5
Gamma
和XYZ
是不同的,因此它们被忽略。
我通过手动比较字符串来完成此操作。是否可以以更简单的方式使用 LINQ 执行此操作?
foreach (var grp in
str.Select((s, i) => new { s, i })
.ToLookup(pair => pair.s, pair => pair.i)
.Where(pair => pair.Count() > 1))
{
Console.WriteLine("{0}: {1}", grp.Key, string.Join(", ", grp));
}
这样的事情应该可以工作:
var elements = str
.Select((Elem, Idx) => new {Elem, Idx})
.GroupBy(x => x.Elem)
.Where(x => x.Count() > 1);
如果您想获得一个将重复的字符串作为键并将索引作为值的Dictionary<string,List<int>>
,只需添加
.ToDictionary(x => x.Key, x => x.Select(e => e.Idx).ToList() );
Where()
后
您可以通过分组来获取非重复字符串,然后您可以获取每个非非重复字符串的索引并将它们分组以为每个字符串创建一个数组:
var distinct = new HashSet<string>(
str.GroupBy(s => s)
.Where(g => g.Count() > 1)
.Select(g => g.Key)
);
var index =
str.Select((s, i) => new {
Str = s,
Index = i
})
.Where(s => distinct.Contains(s.Str))
.GroupBy(i => i.Str).Select(g => new {
Str = g.Key,
Index = g.Select(s => s.Index).ToArray()
});
foreach (var i in index) {
Console.WriteLine("{0} : {1}", i.Str, String.Join(", ", i.Index.Select(n => n.ToString())));
}
输出:
Alpha : 0, 2, 3
Beta : 1, 5