I have the following three classes;
public class City
{
public int CityId { get; set; }
public Region Region { get; set; }
public string Name { get; set; }
}
public class Region
{
public int RegionId { get; set; }
public Country Country { get; set; }
public string Name { get; set; }
}
public class Country
{
public string CountryCode { get; set; }
public string Name { get; set; }
}
I have populated a City List object to contain a number of cities, of which each have a Region and a Country.
Now I want to get a list of all countries for all cities. I've tried the following;
List<City> CityObjectList = GetAllCity();
CityObjectList.Select(r => r.Region).ToList().Select(c => c.Country).ToList();
However, all I get back is all the countries. How can I get the distinct countries ?
You can use:
var allCityCountries = CityObjectList.Select(c => c.Region.Country).ToList();
This list is not distinct. To make the countries unique you could either override Equals
+ GetHashCode
in Country
, implement a custom IEqualityComparer<Country>
for Enumerable.Disinct
or use GroupBy
(slowest but easiest option):
var distinctCountries = CityObjectList
.Select(c => c.Region.Country)
.GroupBy(c => c.CountryCode)
.Select(g => g.First())
.ToList();
The IEqualityComparer<T>
way:
class CountryCodeComparer : IEqualityComparer<Country>
{
public bool Equals(Country x, Country y)
{
if(object.ReferenceEquals(x, y)) return true;
if(x == null || y == null) return false;
return x.CountryCode == y.CountryCode;
}
public int GetHashCode(Country obj)
{
return obj == null ? 0 : obj.CountryCode == null ? 0 : obj.CountryCode.GetHashCode();
}
}
Now you can use Distinct
with an instance of it:
var comparer = new CountryCodeComparer();
distinctCountries = CityObjectList.Select(c => c.Region.Country).Distinct(comparer).ToList();