我有列表A,它是obj A,列表B是obj B.两个列表共享一个属性,我想查找列表B中的所有obj B在A中并将它们拉出来。
所以,前。
列表A是一群人
列表B是一堆名字
两个列表都有personId
现在我想让所有人都拥有列表B中的名字。我在想这样的事情:
class names
{
public int id {get;set;}
public string name {get;set;}
}
class people
{
public int id {get;set;}
public string name {get;set;}
}
var newList = new List<person>();
foreach(var n in names)
{
var person = people.firstordefault(p => p.name == n);
if(person!=null)
{
newList.Add(person);
}
}
}
我想知道LINQ是否有更高效的方法我可以做到这一点,因为它不会是一个列表,每次它可能是数据库我调用它,我不想无缘无故地调用数千个数据库。< / p>
如果我考虑一下,这可能是一个不好的例子。
答案 0 :(得分:1)
此代码:
var newList = new List<person>();
foreach(var n in names)
{
var person = people.firstordefault(p => p.name == n);
if(person!=null)
{
newList.Add(person);
}
}
将产生与以下相同的结果:
var newList = new List<person>();
newList = people.Where(p => names.Contains(p.name)).ToList();
回复您的更新,如果names
是names
对象的列表而不是字符串,您可以执行以下操作:
newList = people.Where(p => names.Select(o => o.name).Contains(p.name)).ToList();
答案 1 :(得分:0)
使用LINQ,您可以这样做:
var intersection = ListA.Intersect(ListB);
然而,这是设置交叉点,这意味着如果ListA和ListB中没有唯一值,则不会获得任何副本。换句话说,如果您有以下内容:
var ListA = new [] { 0, 0, 1, 2, 3 };
var ListB = new [] { 0, 0, 0, 2 };
然后ListA.Intersect(ListB)产生:
{ 0, 2 }
如果你期待:
{ 0, 0, 2 }
然后,当您扫描两个列表时,您将不得不自己维护项目的数量并产生/减少。
答案 2 :(得分:0)
由于你正在处理两个不同的类,你真正想要的是一个连接。
List<Person> people = new List<Person>{new Person{Name = "Mark"},
new Person{Name = "Alice"},
new Person{Name = "Jane"}};
List<string> names = new List<string>{"Mark"};
var query = from p in people
join n in names on p.Name equals n
select p; // will output Person Mark
注意:这具有O(p + n)的时间复杂度(其中p =人数和n =名称数),因为join实现为散列连接。上面的嵌套循环或Where / Contains LINQ查询时间复杂度O(p * n),因为它为每个p迭代n。这可能是也可能不是问题,具体取决于您的收藏品的大小。