linq 将分数相近的学生分组(向上/向下5分)

wdebmtf2  于 2022-12-06  发布在  其他
关注(0)|答案(1)|浏览(108)

我想把分数相近的学生分组,上下各加5分。

public class Students
{
    public string Name {get; set;}
    public int Marks {get; set;}
    public int GroupID {get; set;}
}

public static void Main()
{
    List<Students> students = new List<Students>();
    
    students.Add(new Students { Name = "Aakash", Marks=89, GroupID=0 });
    students.Add(new Students { Name = "Prakash", Marks=85, GroupID=0  });
    students.Add(new Students { Name = "Ramesh", Marks=40, GroupID=0  });
    students.Add(new Students { Name = "Neha", Marks=95, GroupID=0 });
    students.Add(new Students { Name = "Suresh", Marks=93, GroupID=0 });
}

预期输出:

GroupID 1:
Aakash, Prakash

Group 2:
Ramesh
    
GroupID 3:
Neha, Suresh

当学生的分数为4、8、12、16、20和24时会发生什么?
他们将被分成不同的组,以便每组最多有5个点的差异范围:

  • 组1中的4和8
  • 第2组中的12和16
  • 第3组20和24名。
hmae6n7t

hmae6n7t1#

如果你想根据每组中的 * 最高 * 分数来确定每组的分数范围,你可以这样写:

var ordered = students.OrderByDescending(s => s.Marks).ToList();
int groupId = 0;
int nextIndex = 0;
while (nextIndex < ordered.Count)
{
    groupId++;
    var firstInGroup = ordered[nextIndex];
    var group = ordered.Skip(nextIndex).
                        TakeWhile(s => firstInGroup.Marks - s.Marks <= 5).ToList();
    group.ForEach(s => s.GroupID = groupId);
    nextIndex += group.Count;
}

要使此方法可重用并允许在任一方向上进行分组,可以将其转换为helper方法,如下所示:

enum MarkGroupingOption { HighestToLowest, LowestToHighest }

static void SetGroupIds(List<Students> students, int marksThreshold, 
                        MarkGroupingOption groupingOption)
{
    var ordered = (groupingOption == MarkGroupingOption.HighestToLowest
        ? students.OrderByDescending(s => s.Marks).ToList()
        : students.OrderBy(s => s.Marks).ToList());

    int groupId = 0;
    int nextIndex = 0;
    while (nextIndex < ordered.Count)
    {
        groupId++;
        var firstInGroup = ordered[nextIndex];
        var remaining = ordered.Skip(nextIndex);
        var group = (groupingOption == MarkGroupingOption.HighestToLowest
            ? remaining.TakeWhile(s => firstInGroup.Marks - s.Marks <= marksThreshold)
            : remaining.TakeWhile(s => s.Marks - firstInGroup.Marks <= marksThreshold)
            ).ToList();
        group.ForEach(s => s.GroupID = groupId);
        nextIndex += group.Count;
    }
}

用法:

SetGroupIds(students, 5, MarkGroupingOption.HighestToLowest);

SetGroupIds(students, 5, MarkGroupingOption.LowestToHighest);

相关问题