I have a object collection like in the following.
List<Product> productList=new List<Product>();
Structure of the class Product is like in the following.
public class Product
{
public int Id;
public Product(int id)
{
Id=id;
}
public List<SomeOtherList> t;
}
The class Product contains some other list
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);
I want to get "SomeOtherList" objects common to all the Products. For example, for Product Id 1, I should get SomeOtherList object 20 as the common One.
I have written the following LINQ query to achieve this.
List<Product> t=productList
.GroupBy(p => p.Id)
.Where(g => g.Count() == productList.Count)
.Select(x => x.First())
.ToList();
But it does not give me what I want . Can someone point what is wrong with that query ?
What you want is the intersection between your SomeOtherList when the product is some specific value (i.e. 1).
So you need to first select the each Product which has the correct Id and then join their SomeOtherList together and group by the value.
To do this we need to flattern the each SomeOtherList for a Product, which we can do with SelectMany
Projects each element of a sequence to an IEnumerable and flattens the resulting sequences into one sequence.
If we are only intrested in a single Id then we can do the following
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());
This will:
SomeOtherList into one IEnumerableSomeOtherList.valueIf, however, we would like to get the list of all duplicates for each key then we can do the same as for a Single Id but have a first step where we group based on the 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));
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With