我在一个列表中有多个列表对象,我如何获得存在于每个子列表中的项
本文关键字:列表 何获得 于每个 存在 一个 对象 | 更新日期: 2023-09-27 17:54:21
从基本类开始:
public class Car
{
public string Name {get;set;}
}
然后我可以创建这些汽车的列表
List<Car> cars = new List<Car>();
新的步骤是创建List的List,如下所示:
List<List<Car>> allListsOfCars = new List<List<Car>>();
在填充了allListsOfCars之后,我想将它传递给一个函数,该函数将返回每个List列表中存在的汽车。
我知道这听起来很混乱,所以我会试着多解释一点。
如果我有ListA, ListB, ListC都是List类型的,并且现在将它们组合成一个持有列表(列表的列表),那么我如何获得每个列表中存在的所有汽车?例如,如果汽车只存在于ListA中,那么我不感兴趣,它需要存在于ListA和ListB和ListC中,然后我希望将其添加到结果集中并返回。
你需要找到所有子列表的复合交点。
IEnumerable<Car> result=allListsOfCars.FirstOrDefault();
if(result!=null)
{
foreach(var sublist in allListsOfCars.Skip(1))
{
result=result.Intersect(sublist);
}
//enumerate result to run the query
}
也许可以用Aggregate
操作符重写来消除循环,但是Aggregate
读起来不太好。
如果列表很长,你可能会得到一个体面的速度提高使用HashSet
IEnumerable<Car> fst=allListsOfCars.FirstOrDefault();
if(result!=null)
{
HashSet<Car> hs=new HashSet<Car>(fst);
foreach(var sublist in allListsOfCars.Skip(1))
{
hs.IntersectWith(sublist); //in-place operation
}
//enumerate hs
}
确保您的Car
类正确实现相等成员和GetHashCode
,否则这两种方法都不会像预期的那样工作。
如果您可以访问。net 3.5或更高版本,您可以做以下操作:
IEnumerable<Car> carList = allListsOfCar.SelectMany(cars => cars);
编辑:要做列表的交集,你可以这样做:
List<Car> carList = allListsOfCar.Aggregate((left, right) => left.Intersect(right).ToList());
你可以使用聚合,我认为这是一个非常真实的用例:
var allCars = allListOfCars.Aggregate((listAcc,list2)=> listAcc.Concat(list2).ToList());
基本上,对于每个元素(在本例中是list <>),将其连接到累加器,最后得到一个单独的列表。
我尝试了和Adam一样的方法,但是稍微扩展了一下。
IEnumerable<Car> carList = listCars.SelectMany(cars => cars);
List<Car> repeatedCars = new List<Car>();
int length = listCars.Count;
foreach (Car c in cars1)
{
int numberRepeats = carList.Count(car => car.Name == c.Name);
if (numberRepeats == length)
{
repeatedCars.Add(c);
}
}
基本上你需要知道你有多少个列表,并将它们全部保存在一个列表中。然后迭代第一个汽车列表(或其中任何一个),并计算列表中所有其他列表中具有相同名称的汽车的数量。如果重复的长度和次数相同,则该车在所有列表中。