我有一个对象集合,如下所示。
List<Product> productList=new List<Product>();
类产品的结构如下所示。
public class Product
{
public int Id;
public Product(int id)
{
Id=id;
}
public List<SomeOtherList> t;
}
班级产品包含其他一些列表
public class SomeOtherList
{
private int value;
public SomeOtherList(int val)
{
value=val;
}
}
Product prodOne=new Product(1);
List<SomeOtherList> temp_1=new List<SomeOtherList>();
temp_1.Add(new SomeOtherList(10));
temp_1.Add(new SomeOtherList(20));
temp_1.Add(new SomeOtherList(30));
prodOne.t=temp_1;
Product prodTwo=new Product(2);
List<SomeOtherList> temp_2=new List<SomeOtherList>();
temp_2.Add(new SomeOtherList(100));
temp_2.Add(new SomeOtherList(40));
temp_2.Add(new SomeOtherList(30));
prodTwo.t=temp_2;
Product prodThree=new Product(1);
List<SomeOtherList> temp_3=new List<SomeOtherList>();
temp_3.Add(new SomeOtherList(10));
temp_3.Add(new SomeOtherList(20));
prodThree.t=temp_3;
productList.Add(prodOne);
productList.Add(prodTwo);
productList.Add(prodThree);
我想得到&#34; SomeOtherList&#34;所有产品共有的对象。例如,对于产品ID 1,我应该将SomeOtherList对象20作为公共对象。
我编写了以下LINQ查询来实现此目的。
List<Product> t=productList
.GroupBy(p => p.Id)
.Where(g => g.Count() == productList.Count)
.Select(x => x.First())
.ToList();
但它没有给我我想要的东西。有人可以指出该查询的错误吗?
答案 0 :(得分:1)
当产品是某个特定值(即1)时,您SomeOtherList
之间的 intersection 。
因此,您需要先选择具有正确Product
的每个Id
,然后将其SomeOtherList
加在一起并按值分组。
要做到这一点,我们需要 flattern SomeOtherList
的每个Product
,我们可以使用SelectMany
将序列的每个元素投影到IEnumerable,并将生成的序列展平为一个序列。
如果我们只对单个ID感兴趣,那么我们可以执行以下操作
var common1 = productList
.Where(product => product.Id == 1)
.SelectMany(product => product.t)
.GroupBy(groupValue => groupValue.value)
.Where(groupValue => groupValue.Count() > 1)
.Select(values => values.First());
这将:
SomeOtherList
展平为一个IEnumerable SomeOtherList.value
但是,如果我们想获得每个密钥的所有重复项列表,那么我们可以像单个Id那样执行相同的操作,但我们会根据ID对第一步进行分组。
var common = productList
.GroupBy(groupId => groupId.Id)
.Select(groupId => groupId.SelectMany(product => product.t)
.GroupBy(groupValue => groupValue.value)
.Where(groupValue => groupValue.Count() > 1)
.Select(values => values.First().value));
答案 1 :(得分:0)
在单个LINQ查询中很难做到,但是下面的代码应该可以工作。
var min = productList.Min(x=>x.Id);
var max = productList.Max(x=>x.Id);
for(int i = min; i<=max;i++)
{
var products = productList.Where(x=>x.Id = i).ToList();
List<SomeOtherList> cList = new List<SomeOtherList>();
foreach(var product in products)
{
cList.AddRange(product.t);
}
var distinctList = cList.Distinct();
}
答案 2 :(得分:0)
由于嵌套列表,您需要在再次分组之前使用SelectMany对SomeOtherList列表进行分组。我认为这就是你所追求的目标。
var result = productList
.GroupBy(p => p.Id)
.Select(pg =>
new
{
Id = pg.Key,
CommonOtherList = pg
.SelectMany(solg => solg.t)
.GroupBy(solg => solg.value)
.Where(solg => solg.Count() == pg.Count())
.Select(solg => new { OtherId = solg.Key })
});
foreach (var product in result)
{
Console.WriteLine(product.Id);
Console.WriteLine("**Common**");
foreach (var otherProduct in product.CommonOtherList)
{
Console.WriteLine("-->{0}", otherProduct.OtherId);
}
}