Home > Mobile >  LINQ Sub group results with a single query
LINQ Sub group results with a single query

Time:02-09

My model to represent the count for a country is like below

public class GeoStatsModel
{
    public int Id { get; set; } // Country Id
    public string Name { get; set; }  //Country Name
    public int Count { get; set; }
} 

Some of the sample result is like below

List<GeoStatsModel> response;

14 UNITED STATES : 6668
23 CANADA : 768
3 MEXICO : 83
4 PUERTO RICO : 19
35 ISRAEL : 1
46 ECUADOR : 1
57 GERMANY : 3
68 NETHERLANDS : 2
9 COSTA RICA : 1

Can we make further filtering from this list with results of 2 ids

14 UNITED STATES : 6668
23 CANADA : 768
0  Others : [ Sum of Count from all other conuntries] 

The value of country ID 14 & 23 is constant and not going to change

I can fetch the sum of all other country as

List<int> knownCountries = new List<int> { 14, 13 };
int sum_others = response.Where(g => !knownCountries.Contains(g.Id)).Select(g=>g.Count).Sum();

Similarly i can find

 int sum_US=.
 int sum_Canada=..

But is any way we can write this as a linq query to combine the results in a single go

CodePudding user response:

I suggest using named tuples to manipulate with Id, Name and Count

List<GeoStatsModel> response =

...

var result = response
  .Select(item => (
     id    : knownCountries.Contains(item.Id) ? item.Id : 0,
     name  : knownCountries.Contains(item.Id) ? item.Name : "Others",
     value : item.Count
   ))
  .GroupBy(item => (id : item.id, name : item.name), 
           item => item.value)
  .Select(group => (
     id    : group.Key.id,
     name  : group.Key.name,
     count : group.Sum()
   ));

Let's have a look at the result:

string report = string.Join(Environment.NewLine, result
  .Select(item => $"{item.id} {item.name} : {item.count}")
);

Console.Write(report);

I've used tuple (int id, string name, int count) as a final result, but it's posible to return GeoStatsModel as well:

  ...

  .Select(group => new GeoStatsModel() {
     Id    = group.Key.id,
     Name  = group.Key.name,
     Count = group.Sum()
   });
  •  Tags:  
  • Related