【问题标题】:Compare Two Lists and Remove the Same Item比较两个列表并删除相同的项目
【发布时间】:2019-05-07 03:17:28
【问题描述】:

使用foreach,我想遍历两个不同的列表并找到相同的ID,然后删除该项目。

例如:

IList<Student> studentList1 = new List<Student> 
{ 
    new Student() { StudentID = 1, StudentName = "John" },
    new Student() { StudentID = 2, StudentName = "Steve" },
    new Student() { StudentID = 3, StudentName = "Bill" } 
};

IList<Student> studentList2 = new List<Student> 
{                    
    new Student() { StudentID = 3, StudentName = "Bill" },
    new Student() { StudentID = 4, StudentName = "Ram" },
    new Student() { StudentID = 5, StudentName = "Ron" } 
};

如何循环遍历studentList1studentList2,然后删除studentList2 中StudentID = 3 的对象?

【问题讨论】:

  • 你可以使用LINQ方法Where,或者List的方法Remove
  • 请具体then remove that item从两个列表或一个列表中删除它,或者选择我们最喜欢的
  • 抱歉,从 studentList2 中删除该项目
  • 有没有办法使用foreach循环?

标签: c# list


【解决方案1】:

假设您的 Student 类声明如下:

public class Student
{
    public int? StudentID { get; set; }

    public string StudentName { get; set; }

    public override string ToString()
    {
        return $"StudentID={StudentID} StudentName={StudentName}";
    }
}

您可以从System.Linq 使用Where()Any()

var removedList2 = studentList2
    .Where(s2 => !studentList1
    .Any(s1 => s1.StudentID == s2.StudentID));

foreach (var student in removedList2)
{
    Console.WriteLine(student);
}
// StudentID=4 StudentName=Ram
// StudentID=5 StudentName=Ron

但是,上面的方法效率很低,因为您需要扫描整个第一个列表以进行查找,即 O(N)。一种改进是将第一个列表中的 id 存储到 HashSet&lt;int?&gt; 中,然后查找是 O(1) 而不是使用 Contains()

var ids = new HashSet<int?>(studentList1.Select(s1 => s1.StudentID));

var removedList2 = studentList2.Where(s2 => !ids.Contains(s2.StudentID));

foreach (var student in removedList2)
{
    Console.WriteLine(student);
}
// StudentID=4 StudentName=Ram
// StudentID=5 StudentName=Ron

只需 foreach 循环,您就可以使用 Remove():

var ids = new HashSet<int?>();
foreach (var s1 in studentList1)
{
    ids.Add(s1.StudentID);
}

for (var i = studentList2.Count - 1; i >= 0; --i)
{
    if (ids.Contains(studentList2[i].StudentID))
    {
        studentList2.Remove(studentList2[i]);
    }
}

foreach (var student in studentList2)
{
    Console.WriteLine(student);
}
// StudentID=4 StudentName=Ram
// StudentID=5 StudentName=Ron

【讨论】:

  • 谢谢。但是我刚刚意识到我不能使用 linq,因为这两个列表没有使用相同的对象模式。有没有办法使用 foreach 循环?
  • 再次感谢您的修改。但是这次使用 HashSet 我得到了错误:“无法从 System.Collections.Generic.iEnumerable 转换为 System.Collections.Generic.IEqualityComparer”。 Id 实际上设置为 int?因为可以为空。这就是我声明它的方式:public int?学生证 { 得到;放; }
  • @ichachan 不用担心,我将代码修改为使用可为空的int?
  • 我不确定,但如果需要删除两个项目,此代码似乎会失败,因为您使用索引来访问列表成员并将它们从同一个列表中删除。从最后一个迭代到第一个将解决这个问题。 编辑 Validated
  • @SebastianSchumann 感谢您的编辑,错过了那个:P
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2016-05-17
  • 1970-01-01
  • 2011-04-05
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多