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()
});