c# - 如何使用 LINQ 从两个列表中有效地选择某些项目

标签 c# linq

我有这 3 个类:

  • 员工
  • 学生
  • 个人

代码:

public class Employee
{
    public Guid Id { get; set; }
    public string Name { get; set; }
    public int Age { get; set; }
    public string Gender { get; set; }
    public long TimeStamp { get; set; }
}
    
public class Student
{
    public Guid Id { get; set; }
    public string Name { get; set; }
    public int Age { get; set; }
    public long TimeStamp { get; set; }
}
    
public class Person<br>
{
    public string Name { get; set; }
    public int Age { get; set; }
}

我创建了 4 个列表:

var studentList = new List<Student>();// fill the List with a lot of Stundents
var employeeList = new List<Student>(); // fill the List with a lot of employees
var personList1 = new List<Person>();
var personList2 = new List<Person>();

选择所有学生和员工

var allStudents = studentList.Select(a => a); // does not make a lot of sence but for testing 
var allEmployee = employeeList.Select(b => b);

我想将所有学生映射到

personList1.AddRange(allStudents.Select(a => new Person()
            {
               Age = a.Age,
               Name = a.Name
            } ));

我想获取 allStundent 列表中未提及 TimeStape 值的所有员工

var allEmployeesWithDifferentTimeStampThanStundent =
    allEmployee.Where(a => !allStudents.Select(b =>b.TimeStamp).Contains(a.TimeStamp));

再次映射

personList2.AddRange(allEmployeesWithDifferentTimeStampThanStundent.Select
(a => new Person()
    {
    Age = a.Age,
    Name = a.Name
    } ));

合并两个列表

personList1.AddRange(personList2);

是否有更好、更有效的方法来做到这一点?

最佳答案

personList2 变量似乎只是作为投影到 Person 类型的中间体——如果是这种情况,您可以跳过它的创建并使用查询语法像这样:

var personsFromNonMatchingEmployees =
    from employee in allEmployee
    join student in allStudents
    on employee.TimeStamp equals student.TimeStamp into studentsWithMatchingTimeStamp
    where !studentsWithMatchingTimeStamp.Any()
    select new Person { Age = employee.Age, Name = employee.Name };

personList1.AddRange(personsFromNonMatchingEmployees);

这类似于其他 GroupJoin 方法,因为编译器将上述内容转换为 GroupJoin 调用。 join/group-join 的使用必然比 Where..Contains 方法执行得更好,因为它使用了散列——换句话说,它是一种算法上的 Big-O 改进,对于任何多个 Student 或 Employee 实例。

通过在查询中选择 new Person 对象,我可以完全绕过 personList2 列表。我发现我几乎总是能够通过像这样选择项目到我真正感兴趣的类型来消除临时列表。我还遗漏了 () 上的 new Person { .. } 因为编译器不需要它。

羞于改变继承并使 Employee : Person & Student : Person,我认为没有太多需要改进的地方。

关于c# - 如何使用 LINQ 从两个列表中有效地选择某些项目,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14572261/

相关文章:

c# - 如何将在代码隐藏中创建的控件放置在页面上?

c# - 更改 DataGridView 上空图像的外观

c# - 是否构建单独的页面

c# - 查找具有相似和不同字段的记录

c# - Linq 查询中的匿名类型与元组,性能注意事项

c# - XDocument 在一行中写入特定的 XElement

javascript - 将 3 个文本框值从 ASPX 传递给 JavaScript 函数

c# - 为什么 Visual Studio 的编辑器中显示 (-) 标记?

c# - 在 LINQ 中获取不同值的更快方法?

c# - 根据类型组合列表中的元素并求和它们的值,LINQ