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

时间:2011-05-03 16:55:58

标签: c#

从基础课开始:

public class Car
{
  public string Name {get;set;}
}

然后我可以创建这些汽车的列表

List<Car> cars = new List<Car>();

新步骤是拥有此列表的列表,如下所示:

List<List<Car>> allListsOfCars = new List<List<Car>>();

在填充allListsOfCars之后,我想将它传递给一个函数,该函数将返回每个List列表中存在的汽车。

我知道这听起来很混乱,所以我会尝试解释一下。

如果我有ListA,ListB,ListC所有类型List - 现在将它们组合成1个保持列表(列表列表),那么如何才能找回每个列表中存在的所有汽车?例如,如果汽车只存在于ListA中,那么我不感兴趣,它需要存在于ListA和ListB AND ListC中,然后我希望它添加到结果集并返回。

提前致谢。

4 个答案:

答案 0 :(得分:8)

您需要找到所有子列表的复合交集。

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
}

rewrite using the Aggregate运算符可能会消除循环,但Aggregate永远不会很好地读取IMO。

如果列表很长,那么使用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,否则这些方法都不会按预期工作。

答案 1 :(得分:0)

如果您可以访问.NET 3.5或更高版本,则可以执行以下操作:

IEnumerable<Car> carList = allListsOfCar.SelectMany(cars => cars);

编辑:

要执行您可以执行的列表的交集:

List<Car> carList = allListsOfCar.Aggregate((left, right) => left.Intersect(right).ToList());

答案 2 :(得分:0)

你可以使用Aggregate,我认为这是一个非常真实的用例:

var allCars = allListOfCars.Aggregate((listAcc,list2)=> listAcc.Concat(list2).ToList());

基本上,对于每个元素(在本例中是List&lt;&gt;)将它连接到累加器,最后得到一个列表。

答案 3 :(得分:0)

我尝试了与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);
    }
}

基本上,您需要知道您拥有多少个列表,并将它们全部保存在一个列表中。 然后只需遍历第一个汽车列表(或其中任何一个),并使用所有其他列表计算列表中具有相同名称的汽车数量。如果重复的长度和数量相同,那么该汽车就在所有列表中。