为了账号安全,请及时绑定邮箱和手机立即绑定

将夫妇 foreachers 转换为 linq

将夫妇 foreachers 转换为 linq

C#
jeck猫 2021-06-24 18:19:09
所以我有这个代码,问题是,在我的项目中,它必须用 linq 表达式编写,我不知道如何做到这一点,因为有两个列表。有任何想法吗?public void GetLecturersWorkloadStatistics(List<Student> studentList, List<Lecturer> lecturerList){    foreach (Lecturer lecturer in lecturerList)    {        foreach (Student student in studentList)        {            if (lecturer.ModuleName == student.ModuleName &&                lecturer.LastName == student.LecturerLastName &&                lecturer.FirstName == student.LecturerFirstName)            {                lecturer.Credits = lecturer.Credits + lecturer.ModuleValueInCredits;            }        }    }}如上所述,我已经用 linq 完成了内部操作,但我不知道下一步该做什么。public void GetLecturersWorkloadStatistics(List<Student> studentList, List<Lecturer> lecturerList){    foreach (Lecturer lecturer in lecturerList)    {        studentList = (from student in studentList            where lecturer.ModuleName == student.ModuleName &&                  lecturer.LastName == student.LecturerLastName &&                  lecturer.FirstName == student.LecturerFirstName            select student).ToList();    }}
查看完整描述

3 回答

?
隔江千里

TA贡献1906条经验 获得超10个赞

更改您的方法主体以使用 a 的组合Enumerable.Join并Enumerable.All使其在一行中发生


<!-- language: c# -->

lecturerList.Join(studentList, lecturer => new {lecturer.ModuleName, LecturerLastName = lecturer.LastName, LecturerFirstName = lecturer.FirstName}, student=> new {student.ModuleName, student.LecturerLastName, student.LecturerFirstName}, (lecturer, student) => lecturer).All(lecturer=> {lecturer.Credits = lecturer.Credits + lecturer.ModuleValueInCredits; return true;}



查看完整回答
反对 回复 2021-06-27
?
慕雪6442864

TA贡献1812条经验 获得超5个赞

我的 C# 有点生疏,但这里有一种使用扩展方法 LINQ 表示法的方法:


lecturerList

    .SelectMany(lecturer => studentList, Tuple.Create)

    .Where((lecturer, student) =>

        lecturer.ModuleName == student.ModuleName &&

        lecturer.LastName   == student.LecturerLastName &&

        lecturer.FirstName  == student.LecturerFirstName)

    .Select((l, s) => l)

    .ToList()

    .ForEach(lecturer => lecturer.Credits = lecturer.Credits + lecturer.ModuleValueInCredits);

就像@user2023861 一样,您基本上是在创建所有可能元组的列表(“笛卡尔积”):


(0, 0), (1, 0), (2, 0), ..., (lecturers.Length() - 1, students.Length() - 1)

然后应用Where过滤器。然后将其压缩回仅讲师列表。


另一个想法是使用Join:


lecturerList

    .Join(studentList,

        lecturer => Tuple.Create(

            lecturer.ModuleName,

            lecturer.LastName,

            lecturer.FirstName),

        student => Tuple.Create(

            student.ModuleName,

            student.LecturerLastName,

            student.LecturerFirstName),

        (lecturer, student) => lecturer);

    .ToList()

    .ForEach(lecturer => lecturer.Credits = lecturer.Credits + lecturer.ModuleValueInCredits);

如果您首先对数据进行排序,则可以避免这种O(N^2)行为,并N通过利用提前退出来使大数据更快。大多数排序算法都小于,O(N^2)并且通过提前退出,您可以获得类似O(N log N).


当然,这仅在您的数据集确实很大时才值得。:)


查看完整回答
反对 回复 2021-06-27
?
哆啦的时光机

TA贡献1779条经验 获得超6个赞

您正在执行嵌套 foreach 以便对于列表 1 的每个元素您考虑列表 2 的所有元素,这需要在 LINQ 中使用笛卡尔积,这很容易使用 LINQ 语法:


var LecturersToUpdate = from lecturer in lecturerList

       from student in studentList 

       // 2 from clauses one after the other will give the cartesian product of the lists

       where lecturer.ModuleName == student.ModuleName &&

              lecturer.LastName == student.LecturerLastName &&

              lecturer.FirstName == student.LecturerFirstName 

      // After there where we only get the pair of lecturer/student in the cartesian that match your condition, we stop the query there with a select, we could select both the lecturer and student in a new object but here i'm only grabing the lecturer as that's all you're using in the logic of your foreach

     select lecturer;


foreach(var lect in LecturersToUpdate)

{

    lecturer.Credits = lecturer.Credits + lecturer.ModuleValueInCredits;

}

您的更新版本在正确的轨道上,您只需要额外的 from 子句即可获取所有对。


查看完整回答
反对 回复 2021-06-27
  • 3 回答
  • 0 关注
  • 136 浏览

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信