c# - 检查数据是否包含 LINQ 中字符串列表中的值
问题描述
我是 LINQ 的新手。我只想问是否可以检查一个字段是否包含字符串列表中的值。假设我有一个如下定义的字符串列表。
List<String> yearList = new List<string>();
yearList.Add("2012");
yearList.Add("2015");
我也有一堂课Member
:
class Member
{
public string Name {get; set;}
public int Year {get; set;}
...
}
Objectdata
是一个实现的类IEnumerable<Member>
:
IEnumerable<Member> data = ...
因此 data 可能是 aList<Member>
或 a Member[]
,或任何其他表示成员对象的可枚举序列的东西。
year
现在,如果该字段在我的列表中,我想获取数据years yearList
。
或者更准确地说:
要求:给定一个实现的对象数据,IEnumerable<Member>
并给定一个yearList
实现的对象,其中IEnumerable<string>
字符串是一年的文本表示,给我对象data
中的所有成员,其属性值的Year
文本表示至少等于中的值之一yearList
。
例如data
如下:
Name (string) | Year (int)
Ralph | 2012
Rafael | 2012
Bea | 2014
Lee | 2015
yearList
是字符串 {"2012", "2015"} 的序列。我期待这样的结果
Name (string) | Year (int)
Ralph | 2012
Rafael | 2012
Bea | 2014
Lee | 2015
我尝试了以下方法,但没有奏效
data.where(x => x.year.contains(yearList)); <--- THIS CODE NEEDS TO BE CHANGED
这在LINQ中可能吗?
解决方案
Think how you would do it with loops
You might do:
foreach(var d in data){
if(yearList.Contains(d.year))
...
}
But this is different to what you wrote; what you wrote doesn't really make sense:
//data.where(x => x.year.contains(yearList));
//as a loop
foreach(var d in data){
if(d.year.Contains(yearList))
...
}
"If a single year contains a list of years..."
So, then you're working with things like LINQ Where and Select, think of them as like a loop operating over the list of things, and you provide a mini-method that accepts a single parameter, of whatever is in the collection, and returns something else. LINQ will loop over the collection calling your method once per item, passing in the item. You get to choose what the item is called
This is why it helps to have plural names for collections and singular names as the argument in the mini-method (lambda).
var cars = //list of cars
cars.Where(car => car.Maker == "Ford");
Avoid using bland names like x
, because it *doesn't help you keep straight, in your head, what things are. Take a look at this:
var cars = //list of cars
var seekingMakers = new []{"Ford", GM"};
cars.Where(car => seekingMakers.Any(seekingMaker => car.Maker == seekingMaker));
We've named the outer (car
) and the inner (seekingMaker
) to help keep them apart and remind us what they are. seekingMaker
is a single string in an string array seekingMakers
.
So, for your Where
you have to return a boolean from your lambda, and that is used to determine whether the item in the list makes it into the output or not
var winners = //your list of people/year
winners.Where(winner => yearList.Contains(winner.Year));
You can't say winner.Year.Contains(yearList)
- you could say winner.Year.IsContainedWithin(yearList)
- but there's no such thing as IsContainedWithin
- it's the other way round: collection.Contains(singular)
- not "singular contains collection"
Now, you never said what datatype "Year" was in your list of people - maybe it's a string, in which case it makes sense why you'd have yearList
as a string.. but if it's not a string, then I strongly recommend you avoid having it be a different data type, because converting it in place will clutter up your LINQ statement, and also lower performance, because C# will spend a large amount of time converting values over and over again
At any time you want to run a search against some fixed value, match the datatype of the value to the data type of the data being searched:
Do this:
var winners = //your list of people/year with INTEGER years
var years = new[]{ 2012, 2015 };
winners.Where(winner => yearList.Contains(winner.Year));
Not these:
var winners = //your list of people/year with INTEGER years
var years = new[]{ "2012", "2015" };
//don't convert the winner's Year
winners.Where(winner => yearList.Contains(winner.Year.ToString()));
//really don't parse the string years to ints over and over
winners.Where(winner => yearList.Select(stringYear => int.Parse(stringYear)).Contains(winner.Year));
If your data is coming to you as strings, convert it once:
var winners = //your list of people/year with INTEGER years
//pass every item to int.Parse and capture the result to an array you can reuse
var years = stringYearsFromElsewhere.Select(int.Parse).ToArray();
winners.Where(winner => yearList.Contains(winner.Year));
Particularly when working with LINQ, strive to find ways to make the code read like a book..
推荐阅读
- git - Git 不再询问我的 GitHub 用户名和密码。它现在要求我提供“电子邮件”。我如何获得旧版本?
- c# - 使用 FluentValidation 验证集合,返回属性的失败规则错误
- flutter - Flutter:如何在经过一定时间后自动更改页面?
- python - 层 conv1d 的输入 0 与层不兼容::预期 min_ndim=3,发现 ndim=2。收到的完整形状:(无,30)
- docker - 如何使用 Docker 到 Apache 的多个端口?
- visual-studio-code - vscode extensionHost 启动的当前工作目录
- php - 如何使用php从任何文件中获取css文件?
- java - 如何在一个命令中编译一堆“.java”文件?
- python - how to stop this loop from repeating
- java - 从数组中提取json数据