我有这 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/