Linq查询测试多个列表中是否存在

时间:2014-11-17 23:57:41

标签: c# linq

我有类似于以下数据结构

var blueList = new []
    {
        new { Id = 1, Value = 1000 }, 
        new { Id = 2, Value = 1300 }, 
        new { Id = 3, Value = 1500 },
        new { Id = 5, Value = 2100 }
    }.ToList();

var redList = new []
    {
        new { Id = 1, Value = 600 }, 
        new { Id = 3, Value = 950 }, 
        new { Id = 4, Value = 1100 },
        new { Id = 5, Value = 1300 }
    }.ToList();

var greenList = new []
    {
        new { Id = 1, Value = 50 }, 
        new { Id = 2, Value = 180 }, 
        new { Id = 3, Value = 270 },
        new { Id = 4, Value = 430 },
        new { Id = 5, Value = 510 }
    }.ToList();

var colourList = new [] { blueList, redList, greenList }.ToList();

colourList也可以包含一些数量的元素,它们恰好在这个特定的实例中被命名。

如何构建一个linq查询,该查询将为我提供一个新列表,其中只包含列表中所有组中的“ID”?

以下结果排除了Id = 2,因为它不在redList和Id = 4中,因为它不在blueList中。这就是我所追求的目标。

var result = new []
    {
        new { Id = 1, Values = new [] { 1000, 600, 50 } },
        new { Id = 3, Values = new [] { 1500, 950, 270 } },
        new { Id = 5, Values = new [] { 2100, 1300, 510 } }
    };

有什么建议吗?

6 个答案:

答案 0 :(得分:4)

易:

var query = 
    colourList
        .Select(xs => xs.Select(x => new
        {
            Id = x.Id,
            Values = Enumerable.Repeat(x.Value, 1),
        }))
        .Aggregate((xs, vs) =>
            from x in xs
            join v in vs on x.Id equals v.Id
            select new
            {
                Id = x.Id,
                Values = x.Values.Concat(v.Values),
            });

我在您的样本数据上得到了这个结果:

result

当然,您可以扩展colorList以包含任意数量的子列表。

答案 1 :(得分:1)

这似乎工作正常:

var ids = new List<int>();

if (colourList != null && colourList.Any())
{
    // Grab all ids from the first list
    ids = colourList[0].Select(c => c.Id).ToList();

    // Save only the intersection with each additional list
    ids = colourList.Aggregate(ids, (cl1, cl2) => 
        cl1.Intersect(cl2.Select(c => c.Id)).ToList());
}

Console.WriteLine("The common ids are: {0}", string.Join(", ", ids));

答案 2 :(得分:1)

我想出了这个。我只花了一点时间把头伸进双头!任何

var idsInAllColour =
    from colour in colourList
    from id in colour
    where colourList.All(cli => cli.Any(ci => ci.Id == id.Id))
    group id by id.Id;

答案 3 :(得分:1)

我是通过两个步骤完成的:

  • 查找不同的ID
  • 对于每个不同的ID,过滤到所有列表中的ID

    var distinctIds = colourList.SelectMany(o => o).Select(o => o.Id).Distinct();
    
    var matchingIds = distinctIds.Where(id => colourList.All(l => l.Select(o => o.Id).Contains(id)));
    

然后我读了其他答案并意识到你只需要第一个列表中的不同ID:

    var matchingIds = colourList
                        .First()
                        .Where(j => colourList
                                        .Skip(1)
                                        .All(l => l.Any(k => j.Id == k.Id))
                               )
                        .Select(j => j.Id);

这里是.NET小提琴:

https://dotnetfiddle.net/4pPcDO

答案 4 :(得分:1)

我提出了这个解决方案。: -

var result = colourList.SelectMany(x => x)
                       .GroupBy(x => x.Id)
                       .Where(x => x.Count() == colourList.Count())
                       .Select(x => new { Id = x.Key, Values = String.Join(",", x.Select(z => z.Value)) });

以下是完整的Fiddle

答案 5 :(得分:0)

这是另一个!

var commonIds =
    colorList.SelectMany(cList => cList, (c, id) => new {c, id})
             .Where(cList => !colorList.Any(c => c.All(cl => cl.Id != cList.id.Id)))
             .GroupBy(cList => cList.id.Id, cList => cList.id)
             .Select(cList => cList.Key)
             .ToList();

Console.WriteLine(string.Join(", ", commonIds));