Let's say we have a list of cities. Each city knows their country.
Now I want to have a list of all cities of a random country, with there being at least 3 cities in that country.
My best guess is to try to solve this with linq. My idea is that I start by grouping the cities by country
List<City> cities = AssumeWeHaveAPopulatedList();
cities.GroupBy(c => c.country)
But now, how do I filter out those groups with less than 3 items in it?
And how do I then pick a random one of the groups and ungroup that one group again to get the desired list of cities for a random country which has at least 3 cities in that list?
Or maybe there is a different approach without grouping the cities by country first?
CodePudding user response:
You can use Count()
to filter by countries that have >= 3 cities and Random
to pick a random city
Presuming that Country
is a string
property:
Random r = new Random();
List<IGrouping<string, City>> countryGroups = cities
.GroupBy(c => c.Country)
.Where(cg => cg.Count() >= 3)
.ToList();
IGrouping<string, City> randomCountryCity = countryGroups[r.Next(countryGroups.Count)];
So now you have a random group of country-cities. If you want to flatten them to get the Cities in this group, just use it as IEnumerable<City>
which it already implements:
List<City> randomCityList = randomCountryCity.ToList();
Sidenote: I omitted the validation part, you have to ensure that countryGroups
contains Any
items, otherwise you can't access a random one.
CodePudding user response:
A group works like a list, so you can just check the count of the groups:
cities.GroupBy(c => c.country).Where(g => g.Count() >=3)
You can then flatten the groups by using SelectMany
var result = cities
.GroupBy(c => c.country)
.Where(g => g.Count() >=3)
.SelectMany(g => g)
.ToList();
CodePudding user response:
You can use count of the Grouped list like follow:
var newlist = cities.GroupBy(c => c.country)
.Where(x=>x.Count()>=3)
.Select(x=>new { country=x.Key , CityCount=x.Count()})
.ToList();