[英]Using Linq to Filter a List of Objects based on a Condition
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 .我正在解决一个问题,我想从列表
List<RegionData>
删除不需要的对象作为区域名称条件的结果。 As an entry input I receive var data
, which contains a List<CasesDto>
.作为条目输入,我收到
var data
,其中包含List<CasesDto>
。 One item CasesDto
corresponds to all region-based data received on one particular date .一项
CasesDto
对应于在一个特定日期收到的所有基于区域的数据。
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:这是当前的输出示例(为了便于查看,我只包含了两个日期(= 两个 CasesDto)),其中不考虑区域:
[
{
"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:如果应用regionName="ce",这是我想要的输出:
[
{
"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 .我想用lambda 函数解决这个问题。
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?
如何访问 RegionData 模型并仅选择我想要的区域项(基于区域标识符)?
So you have an enumerable sequence of CasesDtos
(plural noun), where every CasesDto
(singular noun) has at least properties Date
and Region
.所以你有一个
CasesDtos
(复数名词)的可枚举序列,其中每个CasesDto
(单数名词)至少有属性Date
和Region
。
Region is an enumerable sequence of RegionDatas
. Region 是一个可枚举的
RegionDatas
序列。 Every RegionData has several properties, among which a property RegionName
.每个 RegionData 都有几个属性,其中一个属性
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
.要求:给定一个
regionName
的字符串值和一系列CasesDtos
,给我每个CasesDto
的Date
和RegionData
,这些RegionData
至少有一个RegionData
,其属性RegionName
的值等于regionName
。
You didn't tell what you want if a CasesDto has two RegionData with the correct RegionName:如果 CasesDto 有两个具有正确 RegionName 的 RegionData,您没有告诉您想要什么:
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. caseDto 有两个具有匹配 RegionName 的 RegionData。 What do you want in your end result: only the Date and one of the RegionDatas?
您希望最终结果是什么:只有日期和 RegionData 之一? which one?
哪一个? Or do you want all RegionDatas with a matching RegionName?
或者你想要所有具有匹配 RegionName 的 RegionDatas?
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.换句话说:对于casesDtos 中的每个CasesDto,创建一个具有两个属性的新对象:CasesDto 的日期和一个属性Region,该属性包含具有匹配RegionName 的此CasesDto 的RegionDatas。 From this Select result, keep only those object that have at least one element in list Region.
从这个 Select 结果中,只保留那些在列表 Region 中至少有一个元素的对象。
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.
使用 ForEach 我们枚举列表并检查我们是否有一个具有给定区域名称的区域。 If so we filter the current list to only contain the correct regions and append this result to a new list.
如果是这样,我们过滤当前列表以仅包含正确的区域并将此结果附加到新列表中。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.