首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >C#获取集合中2个项目的最常用组合

C#获取集合中2个项目的最常用组合
EN

Stack Overflow用户
提问于 2018-11-23 02:55:38
回答 3查看 116关注 0票数 2

我有一个项目集合,如下所示:

代码语言:javascript
复制
    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分组,然后输出两个最受欢迎的项目,就像这些项目被选择了3次一样

代码语言:javascript
复制
FDI AED 
AED FDI
FDI AED

第二个最受欢迎的组合是

代码语言:javascript
复制
AED BPG
BPG AED

所以输出应该是

代码语言:javascript
复制
2 Most popular combinations are
    FDI AED 
    AED BPG

我写了一些代码,但我不知道我怎么可能做到这一点

代码语言:javascript
复制
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

EN

回答 3

Stack Overflow用户

发布于 2018-11-23 03:16:05

IMHO,解决这个问题的最干净的方法是实现一个自定义的相等比较器,它提供了解决当前问题所需的相等语义:

代码语言:javascript
复制
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和自定义比较器:

代码语言:javascript
复制
var mostPopular = 
    students.GroupBy(s => s,
                     new IgnoreElectiveOrderStudentEqualityComparer())
            .OrderByDescending(g => g.Count())
            .Select(g => new
            {
                g.Key.ElectiveOne, 
                g.Key.ElectiveTwo
            })
            .Take(2);
票数 3
EN

Stack Overflow用户

发布于 2018-11-23 03:19:25

诀窍是让两个选修课的顺序不重要,所以alpha第一个总是第一个(因此,如果你有(数学,艺术),它与(艺术,数学)是一样的:

代码语言:javascript
复制
var most_pop = cStudent.GroupBy(x => { if (string.Compare(x.elective1,x.elecitive2) > 0) 
                                         return(new Tuple(x.elective1.x.elective2);
                                       else
                                         return(new Tuple(x.elective2,x.elective1);
                                     },
                                (b, a) => new {  Key = b, Count = a.Count() })
                .OrderyByDesending(x => x.Count).Take(2);

如果你不想要一个带有计数的对象,你可以添加一个键的选择。

票数 2
EN

Stack Overflow用户

发布于 2018-11-23 03:10:55

这对你来说应该是可行的:

代码语言:javascript
复制
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)
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/53436744

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档