通过过滤将列表<>添加到另一个列表<>

Qwe*_*Qwe 4 .net c# list

我有一个模型类:

public class Person 
{
    public int Id { get; set; }
    public string Name { get; set; }
}
Run Code Online (Sandbox Code Playgroud)

当我用这个添加两个列表时:

List<Person> people1 = new List<Person> {
    new Person() { Id = 1, Name = "Name1" },
    new Person() { Id = 2, Name = "Name2" },
    new Person() { Id = 3, Name = "Name3" },
};

List<Person> people2 = new List<Person> {
    new Person() { Id = 1, Name = "Name1" },
    new Person() { Id = 4, Name = "Name4" },
    new Person() { Id = 5, Name = "Name5" },
};

people1.AddRange(people2);
Run Code Online (Sandbox Code Playgroud)

如果personpeople2具有相同idpersonpeople1,我不希望它加入。我怎样才能做到这一点?

Jon*_*eet 10

可以相当容易地但效率低下地使用 LINQ:

people1.AddRange(people2.Where(p2 => !people1.Any(p1 => p1.Id == p2.Id)));
Run Code Online (Sandbox Code Playgroud)

或者您可以先创建一组 ID:

HashSet<int> people1Ids = new HashSet<int>(people1.Select(p1 => p1.Id));
people1.AddRange(people2.Where(p2 => !people1Ids.Contains(p2.id));
Run Code Online (Sandbox Code Playgroud)

第一种方法显然更简单,但是如果您的列表变大,它可能会变慢,因为对于 中的每个元素people2,它都会查看 中的每个元素people1

如果people1很大,第二种方法会快很多。如果它people2很大,那么您将不会获得太多好处。例如,如果people1只包含几个人,那么在散列集中查找 ID 不会比查看列表快得多。

不过,您可以采用完全不同的方法。如果您使您的Person类型IEquatable<Person>基于 ID实现- 或者创建一个IEqualityComparer<Person>这样做,并且如果您不太需要修改现有列表,那么您需要“两个列表的联合”,并且如果您不关心顺序,如果每个列表中的所有条目都是唯一的,或者您不介意删除重复项,则可以使用:

// Specify the comparer as another argument if you need to.
// You could call ToList on the result if you need a list.
var union = people1.Union(people2);
Run Code Online (Sandbox Code Playgroud)

(这是该解决方案的很多条件,但它们很可能都是有效的。)