我在一个列表中有多个列表对象,我如何获得存在于每个子列表中的项

本文关键字:列表 何获得 于每个 存在 一个 对象 | 更新日期: 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);
    }
}

基本上你需要知道你有多少个列表,并将它们全部保存在一个列表中。然后迭代第一个汽车列表(或其中任何一个),并计算列表中所有其他列表中具有相同名称的汽车的数量。如果重复的长度和次数相同,则该车在所有列表中。