使用LINQ从字符串列表中提取int
本文关键字:提取 int 列表 字符串 LINQ 使用 | 更新日期: 2023-09-27 18:20:34
我有一个List<string>
,其中一些字符串是数字。我想把这个子集提取到一个List<int>
中。
我已经用一种非常冗长的方式完成了这项工作,如下所示,但我觉得必须有一种更整洁的LINQ方式来构建它。有什么想法吗?
List<string> myStrs = someListFromSomewhere;
List<int> myInts = new List<int>();
foreach (string myStr in myStrs)
{
int outInt;
if (int.TryParse(myStr, out outInt))
{
myInts.Add(outInt);
}
}
显然,我不需要解决这个问题——这主要是为了我的LINQ教育。
你可以这样做:
int parsed = 0;
myInts = myStrs.Where(x => int.TryParse(x, out parsed)).Select(x => parsed);
这是因为LINQ运算符的执行被推迟,这意味着:
对于myStrs
中的每个项目,首先执行Where
中的代码并将结果写入parsed
。如果TryParse
返回true
,则执行Select
中的代码。在为下一个项目运行整个代码之前,先运行一个项目的整个代码。
LINQ和out
参数不能很好地混合。你可以这样做:
var myInts = myStrs
.Select(s =>
{
int outInt;
return int.TryParse(s, out outInt) ? (int?)outInt : null;
})
.Where(i => i.HasValue)
.Select(i => i.Value)
.ToList();
因为这是为了LINQ教育。。。如果您真的在寻找如何只使用LINQ语法来实现这一点,那么另一个选项是将解析逻辑移动到一个封装结果和值的类中。
var myInts = from val in myStrs
let parserVal = new Parser(val)
where parserVal.IsInt
select parserVal.Val;
Parser是这样的。。。
class Parser
{
public bool IsInt { get; set; }
public int Val { get; set; }
public Parser(string val)
{
int outVal;
IsInt = int.TryParse(val, out outVal);
if (IsInt)
{
Val = outVal;
}
}
}
选择distinct,然后分析每个选择的项目
List<int> myInts = new List<int>();
myInts = myStrs.Distinct().Select(
x =>
{
int parsed;
int.TryParse(x, out parsed);
return parsed;
})
.ToList();