我有一些项目,这里是:

    ID    ELECT1        ELECT2
    1      FDI           AED
    2      BPG           AED
    3      AED           FDI
    4      FDI           AED
    5      GPH           AED
    6      AED           BPG
    7      GPH           FDI


我想将elect1和elect2分组,然后输出最流行的2个,例如
这些项目被选中3次

FDI AED
AED FDI
FDI AED


第二受欢迎的组合是

AED BPG
BPG AED


所以输出将是

2 Most popular combinations are
    FDI AED
    AED BPG


我已经写了一些代码,但我不知道该怎么做

var groups = cStudent.GroupBy(x => new { x.elective1, x.elective2 });
foreach (var group in groups)
{
    Console.WriteLine("{0} / {1}:", group.Key.elective1, group.Key.elective2);
    foreach (var item in group)
    {
        Console.WriteLine("  {0} ({1})", item.elective1, item.elective2);
    }
}


所以这就是我在代码中得到的东西,只是不知道如何完成。
IMAGE

最佳答案

恕我直言,解决此问题的最干净方法是实现自定义相等比较器,该比较器提供解决当前问题所需的相等语义:

class IgnoreElectiveOrderStudentEqualityComparer
    : IEqualityComparer<Student>
{
    public bool Equals(Student x, Student y)
        => (x.ElectiveOne == y.ElectiveOne &&
            x.ElectiveTwo == y.ElectiveTwo) ||
           (x.ElectiveOne == y.ElectiveTwo &&
            x.ElectiveTwo == y.ElectiveOne);

    public int GetHashCode(Student obj)
        => obj.ElectiveOne.GetHashCode() ^
           obj.ElectiveTwo.GetHashCode();
}


现在,您只需使用GroupBy和自定义比较器:

var mostPopular =
    students.GroupBy(s => s,
                     new IgnoreElectiveOrderStudentEqualityComparer())
            .OrderByDescending(g => g.Count())
            .Select(g => new
            {
                g.Key.ElectiveOne,
                g.Key.ElectiveTwo
            })
            .Take(2);

08-06 02:33