如何选择非独特元素及其索引

时间:2011-04-29 10:11:58

标签: c# linq

 List<string> str = new List<string>() {
   "Alpha", "Beta", "Alpha", "Alpha", "Gamma", "Beta", "XYZ" };

预期输出:

 String | Indexes
 ----------------------------
 Alpha  | 0, 2, 3
 Beta   | 1, 5

GammaXYZ是截然不同的,它们会被忽略。

我通过手动比较字符串来完成此操作。是否有可能以更简单的方式使用 LINQ 来实现?

3 个答案:

答案 0 :(得分:5)

这样的事情应该有效:

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()

之后

答案 1 :(得分:5)

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));
}

答案 2 :(得分:2)

您可以通过分组获取非独特字符串,然后您可以获取每个非不同字符串的索引并将它们分组以为每个字符串创建一个数组:

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