Home > Software design >  Get a list of all items with a object value from a list, but the value has to exist at least 3 times
Get a list of all items with a object value from a list, but the value has to exist at least 3 times

Time:10-10

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();
  • Related