如何选择非重复元素及其索引


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

预期产出:

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

GammaXYZ是不同的,因此它们被忽略。

我通过手动比较字符串来完成此操作。是否可以以更简单的方式使用 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

相关内容

  • 没有找到相关文章

最新更新