Reputation: 624
Sorry about the question, I couldn't build the sentence. Here is what I have,
class Brand{
int ModelId;
string name;
}
class Gallery{
IList<Brand> brands;
...
public BrandList{
get{ return brands; }
}
}
I have a list of Gallery. Like this,
IList<Gallery> galleries;
and each Gallery in galleries have many Brands in it. For example, galleries have 6 Gallery object in it. And each gallery has Brands in it. Like this,
Gallery1.Brandlist => Audi, Ford
Gallery2.BrandList => Mercedes,Volvo
Gallery3.BrandList => Subaru
Gallery4.BrandList => Renault
Gallery5.BrandList => Subaru
Gallery6.BrandList =>
What I am trying to get with LINQ is a list of Brands that are distinct of all above's first brand only(so I won't take Ford and Volvo even they are in the list). A gallery doesn't have to have a Brand in their list. So it might be empty as Gallery6. The Output should be,
{Audi, Mercedes, Subaru, Renault}
I don't know how I can do this with LINQ. I tried SelectMany
but all I can do with LINQ is simple (p=>p.Something = (int) something).ToList()
. I couldn't figure out how to do it.
Upvotes: 2
Views: 70
Reputation: 460138
Use SelectMany
and Distinct
:
IEnumerable<string> allUniqueBrands = allGalleries
.SelectMany(g => g.BrandList.Select(b => b.Name)).Distinct();
In query syntax:
IEnumerable<string> allBrands = from gallery in allGalleries
from brand in gallery.BrandList
select brand.Name;
IEnumerable<string> allUniqueBrands = allBrands.Distinct();
Edit: Now i got it, you need only the first brands of each BrandList.
If you want to select the Brand
you have to provide a custom IEqualityComparer<Brand>
which you can use in Distinct
. If you neeed a List<Brand>
, just call ToList()
at the end.
Here's an IEqualityComparer<Brand>
for Distinct
(or Union,Intesect,Except etc):
public class BrandComparer : IEqualityComparer<Brand>
{
public bool Equals(Brand x, Brand y)
{
if (x == null || y == null) return false;
return x.Name.Equals(y.Name, StringComparison.OrdinalIgnoreCase);
}
public int GetHashCode(Brand obj)
{
if (obj == null) return int.MinValue;
return obj.Name.GetHashCode();
}
}
and here's the distinct list of all (first) brands:
List<Brand> uniqueFirstBrands = allGalleries
.Where(g => g.BrandList != null && g.BrandList.Any())
.Select(g => g.BrandList.First())
.Distinct(new BrandComparer())
.ToList();
Upvotes: 4
Reputation: 57210
This should work:
var brands = galleries.Where(x => x.BrandList.Any())
.Select(x => x.BrandList.First().Name)
.Distinct();
If you want the result being a collection of Brand objects instead of strings, you could do this:
var brands = galleries.Where(x => x.BrandList.Any())
.GroupBy(x => x.BrandList.First().Name)
.Select(g => g.First().BrandList.First());
Upvotes: 3