Linq Order通过对具有相同集合的对象进行分组

彼得罗莫洛伊

我有一组对象,它们本身包含一组对象。

private class Pilot
{
    public string Name;
    public HashSet<string> Skills;
}

这里是一些测试数据:

public void TestSetComparison()
{
    var pilots = new[] 
    {
        new Pilot { Name = "Smith", Skills = new HashSet<string>(new[] { "B-52", "F-14" }) },
        new Pilot { Name = "Higgins", Skills = new HashSet<string>(new[] { "Concorde", "F-14" }) },
        new Pilot { Name = "Jones", Skills = new HashSet<string>(new[] { "F-14", "B-52" }) },
        new Pilot { Name = "Wilson", Skills = new HashSet<string>(new[] { "F-14", "Concorde" }) },
        new Pilot { Name = "Celko", Skills = new HashSet<string>(new[] { "Piper Cub" }) },
    };

我想OrderBy在Linq中使用

  • 史密斯和琼斯因为他们乘坐同一架飞机而被命令在一起
  • 希金斯和威尔逊因为乘坐同一架飞机而被命令在一起
  • 希金斯和威尔逊在史密斯·琼斯之前还是之后都没关系
  • 最好是史密斯在琼斯之前(稳定排序),但这不是太重要

我想我需要实现一个IComparer<Pilot>传递给,OrderBy但不知道如何处理“无所谓”方面(上面)和稳定排序。

更新:

我希望输出是相同五个对象数组顺序不同 Pilot

德米特里·拜琴科(Dmitry Bychenko)

GroupBy您必须IEqualityComparer<T>为类型进行实现时HashSet<string>例如)

private sealed class MyComparer : IEqualityComparer<HashSet<string>> {
  public bool Equals(HashSet<string> x, HashSet<string> y) {
    if (object.ReferenceEquals(x, y))
      return true;
    else if (null == x || null == y)
      return false;

    return x.SetEquals(y);
  }

  public int GetHashCode(HashSet<string> obj) {
    return obj == null ? -1 : obj.Count;
  }
}

然后使用它:

 IEnumerable<Pilot> result = pilots
    .GroupBy(pilot => pilot.Skills, new MyComparer())
    .Select(chunk => string.Join(", ", chunk
       .Select(item => item.Name)
       .OrderBy(name => name))); // drop OrderBy if you want stable Smith, Jones

 Console.WriteLine(string.Join(Environment.NewLine, result));

结果:

 Jones, Smith
 Higgins, Wilson
 Celko

编辑:如果要重新排列一个数组,则添加SelectMany()使分组扁平化,最后一个ToArray()

 var result = pilots
    .GroupBy(pilot => pilot.Skills, new MyComparer())
    .SelectMany(chunk => chunk)
    .ToArray();

 Console.WriteLine(string.Join(", ", result.Select(p => p.Name)));

结果:

 Jones, Smith,
 Higgins, Wilson,
 Celko

请注意,string.join在一行中组合了每个组的名称,即,Jones, Smith两者具有相同的技能。

DotNetFiddle的身份运行

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章