C#在收藏中获得2件物品的最受欢迎组合

时间:2018-11-22 18:55:38

标签: c# list linq

我有一些物品,这里是:

Name  Surname  MI  
Mary  White    S   
Bob   Red      A   
Mark  Blue         
      Black        

而且我想对当选者1和当选者2进行分组,然后输出最受欢迎的2个,例如 这些项目被选中3次

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

第二受欢迎的组合是

FDI AED 
AED FDI
FDI AED

所以输出将是

AED BPG
BPG AED

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

2 Most popular combinations are
    FDI AED 
    AED BPG

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

3 个答案:

答案 0 :(得分:3)

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

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

答案 1 :(得分:2)

诀窍是让两个选修课的顺序无关紧要,因此Alpha优先始终是第一个(因此,如果您拥有(数学,艺术),则它与(艺术,数学)相同:

pywin32

如果您不希望带有计数的对象,则可以添加键的选择。

答案 2 :(得分:0)

这应该对您有用:

cStudent
    .Select(x => new[] { x.elective1, x.elective2 }.OrderBy(y => y).ToArray())
    .GroupBy(x => Tuple.Create(x[0], x[1]), (k, g) => new { Elective = k, Count = g.Count() })
    .OrderByDescending(x => x.Count)
    .Select(x => new { elective1 = x.Elective.Item1, elective2 = x.Elective.Item2 })
    .Take(2)