我有一个项目集合,如下所示:
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次一样
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
发布于 2018-11-23 03:16:05
IMHO,解决这个问题的最干净的方法是实现一个自定义的相等比较器,它提供了解决当前问题所需的相等语义:
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);发布于 2018-11-23 03:19:25
诀窍是让两个选修课的顺序不重要,所以alpha第一个总是第一个(因此,如果你有(数学,艺术),它与(艺术,数学)是一样的:
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);如果你不想要一个带有计数的对象,你可以添加一个键的选择。
发布于 2018-11-23 03:10:55
这对你来说应该是可行的:
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)https://stackoverflow.com/questions/53436744
复制相似问题