[英]Compare two list using linq in C#
我們有下面的學生列表,我想通過比較學生姓名來比較兩個列表(來源、目的地)。 如果學生姓名發生變化,那么我們需要執行更新查詢,以更新新的學生姓名。
Public Class Student
{
public int StudentId { get; set; }
public int StudentName { get; set; }
}
我們需要將學生名單與來源和目的地進行比較。
IList<Student> studentList1 = new List<Student>() {
new Student() { StudentId = 1, StudentName = "John", Age = 18 } ,
new Student() { StudentId = 2, StudentName = "Steve", Age = 15 }
};
IList<Student> studentList2 = new List<Student>() {
new Student() { StudentId = 1, StudentName = "Michaiel", Age = 18 } ,
new Student() { StudentId = 2, StudentName = "Mike", Age = 15 } ,
};
所以,到目前為止,我們正在考慮使用SequenceEqual
方法來比較兩個列表。 那么,這種方法是否也比較區分大小寫的值和任何其他更好的替代方法?
這種方法可以用於其他數據類型,如 boolean、int 等。
對此的任何幫助表示贊賞!
像大多數 LINQ 方法一樣, SequenceEquals接受一個comparer
參數,該參數允許您使用不同的比較來比較元素。
您可以直接實現 IEqualityComparer 接口或從EqualityComparer繼承:
class StudentNameComparer: EqualityComparer<Student>
{
public override bool Equals(Student st1, Student st2)
{
return String.Equals(st1?.StudentName,st2?.StudentName);
}
public override int GetHashCode(Student st)
{
return st.Name.GetHashCode();
}
}
這允許您檢查差異:
var hasDiffs=studentList1.SequenceEquals(studentList2, new StudentNameComparer());
除了有一個比較器。 您可以通過以下方式找到實際差異:
var diffs=studentList1.Except(studentList2,new StudentNameComparer());
.NET 中的字符串比較區分大小寫。 如果您想使用不區分大小寫的比較,您可能應該提取並比較名稱。 您可以將String.Equals與所需的StringComparison參數一起使用,例如: String.Equals(st1.StudentName,st2.StudentName,StringComparison.OrdinalIgnoreCase)
但是 hash 代碼呢?
StringComparer已經實現了適當的比較和 hash 代碼,因此更易於使用:
var studentNames1=studentList1.Select(st=>st.StudentName);
var studentNames2=studentList2.Select(st=>st.StudentName);
var haveDiffs=studentNames1.SequenceEqual(studentName2,StringComparer.OrdinalIgnoreCase);
如果學生姓名發生變化,那么我們需要執行更新查詢,以更新新的學生姓名。
根據該陳述,您需要了解的不僅僅是兩個列表是否包含相同的成員。 在我看來,您應該遍歷第一個列表並查看第二個列表中是否有更新的名稱:
foreach (var student in studentList1)
{
var otherStudent = studentList2.FirstOrDefault(other =>
other.SudentId == student.StudentId &&
!other.StudentName.Equals(student.StudentName, StringComparison.OrdinalIgnoreCase));
if (otherStudent != null)
{
// Update student record with student.StudentId to otherStudent.StudentName
}
}
同樣,您可以使用以下內容獲取所有具有新名稱的學生:
var studentsWithNewNames = studentList2.Where(s2 =>
studentList1.Any(s1 =>
s1.StudentId == s2.StudentId &&
!s1.StudentName.Equals(s2.StudentName, StringComparison.OrdinalIgnoreCase)));
foreach (var newNameStudent in studentsWithNewNames)
{
// Update student with newNameStudent.StudentId to newNameStudent.StudentName
}
或者你可以 go 完全 linq ,然后做:
studentList2.Where(s2 => studentList1.Any(s1 =>
s1.StudentId == s2.StudentId &&
!s1.StudentName.Equals(s2.StudentName, StringComparison.OrdinalIgnoreCase)))
.ToList()
.ForEach(student =>
{
// update student.StudentId with student.StudentName
});
另請注意,您不應將Age
作為屬性存儲,因為它在不斷變化。 您應該存儲DateOfBirth
,然后將Age
顯示為計算字段。 並且Name
應該是一個string
(另請注意,您不需要在屬性名稱中重復 class 名稱):
public class Student
{
public int Id { get; set; }
public string Name { get; set; }
public DateTime DateOfBirth { get; set; }
public TimeSpan Age => DateTime.Now - DateOfBirth;
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.