I am solving an issue where I want to remove unwanted objects from a list List<RegionData>
as a result of a region name condition.
As an entry input I receive var data
, which contains a List<CasesDto>
. One item CasesDto
corresponds to all region-based data received on one particular date.
These are two of my classes that I am using as an example:
public class CasesDto
{
public DateTime Date {get; set;}
public List<RegionData> Region {get; set;}
}
and
public class RegionData
{
public string RegionName {get; set;}
public int DailyActiveCases {get; set;}
public int DeceasedToDate {get; set;}
}
This is the current output example (I only included two dates (= two CasesDto) for easy-to-view purpose) where region is not taken into consideration:
[
{
"date": "2021-05-22T00:00:00",
"region": [
{
"regionName": "ce",
"dailyActiveCases": 615,
"deceasedToDate": 568
},
{
"regionName": "kk",
"dailyActiveCases": 170,
"deceasedToDate": 197
},
{
"regionName": "kp",
"dailyActiveCases": 278,
"deceasedToDate": 166
}
]
},
{
"date": "2021-05-23T00:00:00",
"region": [
{
"regionName": "ce",
"dailyActiveCases": 613,
"deceasedToDate": 570
},
{
"regionName": "kk",
"dailyActiveCases": 167,
"deceasedToDate": 197
},
{
"regionName": "kp",
"dailyActiveCases": 277,
"deceasedToDate": 166
}
]
}
]
This is the output I would want if regionName="ce" is applied:
[
{
"date": "2021-05-22T00:00:00",
"region": [
{
"regionName": "ce",
"dailyActiveCases": 615,
"deceasedToDate": 568
}
]
},
{
"date": "2021-05-23T00:00:00",
"region": [
{
"regionName": "ce",
"dailyActiveCases": 613,
"deceasedToDate": 570
}
]
}
]
I would like to solve this problem with lambda functions.
My attempt:
data = data.ForEach(x => x.Region.Where(t => t.RegionName == region)).ToList();
However, I receive a mismatch in return type. How can I access RegionData model and select only a region item (based on region identifier) that I want?
CodePudding user response:
So you have an enumerable sequence of CasesDtos
(plural noun), where every CasesDto
(singular noun) has at least properties Date
and Region
.
Region is an enumerable sequence of RegionDatas
. Every RegionData has several properties, among which a property RegionName
.
I think you've described the following requirement:
Requirement: given a string value for
regionName
, and a sequence ofCasesDtos
, give me theDate
and theRegionData
of everyCasesDto
that has at least oneRegionData
with a value for propertyRegionName
that equalsregionName
.
You didn't tell what you want if a CasesDto has two RegionData with the correct RegionName:
string regionName = "CA";
var casesDto = new CasesDto
{
Date = ...
Region = new List<RegionData>()
{
new RegionData()
{
RegionName = "CA",
...
},
new RegionData()
{
RegionName = "CA",
...
}
}
}
casesDto has two RegionDatas with a matching RegionName. What do you want in your end result: only the Date and one of the RegionDatas? which one? Or do you want all RegionDatas with a matching RegionName?
Anyway, the solution is:
string regionName = "CA";
IEnumerable<CasesDto> casesDtos = ...
// from every CasesDto, make one object, containing the Date, and a property
// Region, which contains only those RegionDatas that have a value for property
// RegionName that equals regionName
var result = casesDtos.Select(casesDto => new
{
Date = casesDto.Date,
// keep only those Regions that have a matching RegionName:
Region = casesDto.Region
.Where(region => region.RegionName == regionName)
.ToList(),
}
// From this selection, keep only those object that have at least one Region:
.Where(casesDto => casesDto.Region.Any());
In words: for every CasesDto in casesDtos, make one new object with two properties: the Date of the CasesDto, and a property Region which contains the RegionDatas of this CasesDto that have a matching RegionName. From this Select result, keep only those object that have at least one element in list Region.
CodePudding user response:
var cases = new List<CasesDto>{
new CasesDto{
Date = DateTime.Now,
Region = new List<RegionData> {
new RegionData{
RegionName = "CE"
},
new RegionData{
RegionName = "DE"
}
}
},
new CasesDto{
Date = DateTime.Now.AddDays(10),
Region = new List<RegionData> {
new RegionData{
RegionName = "DE"
}
}
}
};
var filteredCases = new List<CasesDto>();
var regionName = "CE";
cases.ForEach(c => {
if(c.Region.Any(x => x.RegionName == regionName)){
c.Region = c.Region.Where(x => x.RegionName == regionName).ToList();
filteredCases.Add(c);
}
});
Somewhat simplified to save me some time. Using ForEach we enumerate over the list and check if we have a region with given regionnames. If so we filter the current list to only contain the correct regions and append this result to a new list.