我有类似于以下数据结构
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 } }
};
有什么建议吗?
答案 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),
});
我在您的样本数据上得到了这个结果:
当然,您可以扩展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
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小提琴:
答案 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));