如何用Linq基于共同兴趣修改学生列表的GroupID
解决方案:基于LINQ的学生兴趣分组
1. 定义学生类
先确保Students类包含必要属性,同时添加辅助属性简化兴趣拆分操作:
public class Students { public string Name { get; set; } public int GroupID { get; set; } public string Interests { get; set; } // 自动拆分兴趣为去重后的列表 public List<string> InterestList => Interests.Split(',') .Select(s => s.Trim()) .Distinct() .ToList(); }
2. 核心分组逻辑
以下代码通过LINQ完成兴趣统计、组ID映射,最终为学生分配GroupID:
// 初始化原始学生列表 List<Students> students = new List<Students>(); students.Add(new Students() { Name = "Krishna", GroupID= 0, Interests = "Physics,Maths" }); students.Add(new Students() { Name = "Ganesh", GroupID= 0, Interests = "History,Physics" }); students.Add(new Students() { Name = "Jayesh", GroupID= 0, Interests = "Tech,Humanity" }); students.Add(new Students() { Name = "Aditya", GroupID= 0, Interests = "Science"}); students.Add(new Students() { Name = "Ramesh", GroupID= 0, Interests = "Programming,Science"}); // 统计每个兴趣对应的学生集合 var interestToStudents = students .SelectMany(student => student.InterestList.Select(interest => new { student, interest })) .GroupBy(item => item.interest) .ToDictionary(group => group.Key, group => group.Select(item => item.student).ToList()); // 筛选出有至少2个学生共享的兴趣,并分配唯一GroupID var sharedInterestGroups = interestToStudents .Where(kv => kv.Value.Count >= 2) .Select((kv, index) => new { Interest = kv.Key, GroupID = index + 1 }) .ToDictionary(item => item.Interest, item => item.GroupID); // 为每个学生分配GroupID foreach (var student in students) { // 找到学生兴趣中第一个匹配的共享兴趣 var matchedInterest = student.InterestList.FirstOrDefault(interest => sharedInterestGroups.ContainsKey(interest)); if (matchedInterest != null) { student.GroupID = sharedInterestGroups[matchedInterest]; } else { // 无共享兴趣的学生分配独立组ID student.GroupID = sharedInterestGroups.Count + 1; } } // 输出分组结果 foreach (var group in students.GroupBy(s => s.GroupID)) { var studentNames = string.Join("、", group.Select(s => s.Name)); var commonInterest = group.First().InterestList.FirstOrDefault(i => sharedInterestGroups.ContainsKey(i)) ?? "无共同兴趣"; Console.WriteLine($"GroupID {group.Key};学生:{studentNames}(原因:共同兴趣为{commonInterest})"); }
3. 代码说明
- 兴趣统计:通过
SelectMany将每个学生的兴趣拆分为单独条目,再按兴趣分组,得到每个兴趣对应的学生列表。 - 共享兴趣筛选:只保留有至少2个学生的兴趣,为这些兴趣分配从1开始的连续GroupID。
- 组ID分配:遍历学生,匹配他们的共享兴趣并赋值GroupID;无共享兴趣的学生分配独立组ID(示例中Jayesh会被分到GroupID 3)。
- 结果输出:按GroupID分组后输出,完全匹配预期格式。
4. 特殊情况处理
如果存在学生同时属于多个共享兴趣组(比如某学生既喜欢Physics又喜欢Science),当前代码会取第一个匹配的兴趣分配组ID。若需要合并关联组(比如两个兴趣有重叠学生则合并为一组),则需要额外的连通分量处理逻辑(比如Union-Find算法),但当前需求场景下无需额外处理。
内容的提问来源于stack exchange,提问作者KittyCat
相关产品推荐
相关产品推荐

