我有以下列表。
一个包含Person对象的列表有Id&名称属性。 People对象的其他列表有Id,Name&地址属性。
List<Person> p1 = new List<Person>();
p1.Add(new Person() { Id = 1, Name = "a" });
p1.Add(new Person() { Id = 2, Name = "b" });
p1.Add(new Person() { Id = 3, Name = "c" });
p1.Add(new Person() { Id = 4, Name = "d" });
List<People> p2 = new List<People>();
p2.Add(new People() { Id = 1, Name = "a", Address=100 });
p2.Add(new People() { Id = 3, Name = "x", Address=101 });
p2.Add(new People() { Id = 4, Name = "y", Address=102 });
p2.Add(new People() { Id = 8, Name = "z", Address=103 });
想要过滤列表,所以我使用下面的代码。但代码返回ID列表。我希望List of People对象具有匹配的ID。
var filteredList = p2.Select(y => y.Id).Intersect(p1.Select(z => z.Id));
答案 0 :(得分:7)
您最好使用Join
var filteredList = p2.Join(p1,
people => people.Id,
person => person.Id,
(people, _) => people)
.ToList();
该方法会根据您提供的密钥匹配两个列表中的项目 - Id
类的People
和Id
类的Person
。
对于people.Id == person.Id
的每个对,它应用选择器函数(people, _) => people
。函数说为每对匹配的people
和person
只给我people
个实例;我不在乎person
。
答案 1 :(得分:0)
这样的事情可以解决问题:
var result= p1.Join(p2, person => person.Id, people => people.Id, (person, people) => people);
答案 2 :(得分:0)
如果您的列表足够大,则应使用散列集合来过滤它并提高性能:
var hashedIds = new HashSet<int>(p1.Select(p => p.Id));
var filteredList = p2.Where(p => hashedIds.Contains(p.Id)).ToList();
这将非常快速地工作和工作,因为像Dictionary或HashSet这样的哈希集合允许执行具有几乎O(1)
复杂度的快速查找(这实际上意味着为了找到具有某些哈希编译器的元素确切知道在哪里查找用List<T>
查找某些元素编译器必须循环整个集合才能找到它。
例如,行:p2.Where(p => p1.Contains(p.Id)).ToList();
具有O(N2)的复杂性,因为同时使用.Where和.Contains将形成嵌套循环。
不要使用最简单的答案(和方法),使用最适合您需求的答案。
Simple performance test against .Join() ...
更大的收藏品会产生更大的差异。