gpt4 book ai didi

c# - 如何在 C# 中按列表列表分组并将其合并为单个列表而不重复?

转载 作者:行者123 更新时间:2023-12-04 10:08:49 24 4
gpt4 key购买 nike

我有一个名为 studentdetails 的类和一个名为 students 的属性,它是 studentdetails 的列表。

public class studentdetails 
{
public int SubjectId {get ; set; }
public int studentId { get; set; }
public int ClassId { get; set; }
}

List<studentdetails> students = new List<studentdetails>()
{
new studentdetails() { studentId = 1, SubjectId = 1, ClassId = 1 },
new studentdetails() { studentId = 2, SubjectId = 2, ClassId = 1 },
new studentdetails() { studentId = 3, SubjectId = 1, ClassId = 2 },
new studentdetails() { studentId = 1, SubjectId = 3, ClassId = 2 },
new studentdetails() { studentId = 1, SubjectId = 3, ClassId = 1 }
};

我必须创建一个包含学生列表(其中包含作为属性的 sbject 列表)作为属性的类列表,而不重复类、学生和主题(如果它已经存在)。

例子:
public class Class
{
public int ClassId { get; set; }
public Lits<student> students { get; set; }
}
public class student
{
public int StudentId { get; set; }
public Lits<Subject> subjects { get; set; }
}
public class Subject
{
public int SubjectId { get; set; }
}

例如:
引用以上学生详情
class(1) -student(1) -subject(1)
-subject(3)
-student(2) -subject(2)

class(2) -student(3) -subject(1)
-student(1) -subject(3)

最佳答案

下一个方法可以用来解决这个问题:

List<Class> classes = students
// This GroupBy creates groups by ClassId:
// (ClassId) -> (List of Students).
.GroupBy(s => s.ClassId)
.Select(c => new Class
{
ClassId = c.Key,
Students = c
// This GroupBy for given Class creates groups by StudentId:
// (StudentId) -> (List of Subjects).
.GroupBy(s => s.StudentId)
.Select(s => new Student
{
StudentId = s.Key,
Subjects = s
// This GroupBy for given Class and Student removes
// duplicate values of SubjectId. If you can guarantee
// that for given Class and Student will not be duplicate
// values of SubjectId then you can remove this GroupBy.
// If you remove this GroupBy then you need to change
// expression inside Select to the following:
// new Subject { SubjectId = t.SubjectId }.
.GroupBy(t => t.SubjectId)
.Select(t => new Subject { SubjectId = t.Key })
.ToList()
}).ToList()
}).ToList();

这里是 complete sample这表明了这种方法。

@Thaks 在评论中问道:

If there is class name, student name and aсtivity name along with ids. Then how can I map accordingly to the instance?



如果您还需要映射 id 以外的属性那么你应该使用 GroupBy 的下一个重载方法: GroupBy(keySelector, comparer) .使用这种方法,我们可以使用 StudentDetails 的实例。类作为键并指定 comparer为他们。

首先我们应该创建 comparer , 实现接口(interface) IEqualityComparer 的类.在我们的示例中,我们可以使用单个 comparer类来执行所有三个 GroupBy操作,因为我们所有的 GroupBy使用 int Id 执行操作属性(property)。通常每个 GroupBy操作使用自己的 comparer因为大多数时候不同 GroupBy使用不同的键(不同的数据类型,不同数量的分组属性)执行操作。以下是我们如何实现 comparer :
// For demo I simplified implementation of the Equals and GetHashCode
// methods by excluding null checks. In the documentation of
// IEqualityComparer you can find implementation with null checks.
public class ComparerById<T> : IEqualityComparer<T>
{
private readonly Func<T, int> _keySelector;

public ComparerById(Func<T, int> keySelector) => _keySelector = keySelector;

public bool Equals(T x, T y) => _keySelector(x) == _keySelector(y);

public int GetHashCode(T obj) => _keySelector(obj);
}

然后使用这个 comparer我们可以执行所需的 GroupBy :
List<Class> classes = students
// Now key of each group has type StudentDetails, therefore later we
// will be able to use properties of StudentDetails such as ClassName.
// Here to compare keys of type StudentDetails we use comparer:
// new ComparerById<StudentDetails>(s => s.ClassId);
// It means that we create groups by ClassId.
.GroupBy(s => s, new ComparerById<StudentDetails>(s => s.ClassId))
.Select(c => new Class
{
ClassId = c.Key.ClassId,
ClassName = c.Key.ClassName,
Students = c
// Here we create groups by StudentId.
.GroupBy(s => s, new ComparerById<StudentDetails>(s => s.StudentId))
.Select(s => new Student
{
StudentId = s.Key.StudentId,
StudentName = s.Key.StudentName,
Subjects = s
// Here we create groups by SubjectId.
.GroupBy(t => t, new ComparerById<StudentDetails>(t => t.SubjectId))
.Select(t => new Subject {SubjectId = t.Key.SubjectId, SubjectName = t.Key.SubjectName})
.ToList()
}).ToList()
}).ToList();

这里是 complete sample这表明了这种方法。

关于c# - 如何在 C# 中按列表列表分组并将其合并为单个列表而不重复?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/61440794/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com