使用LINQ从字符串列表中提取int
我有一个List
,其中一些字符串是数字。 我想将此子集提取到List
。
我以相当冗长的方式完成了这个 – 如下所示 – 但我感觉必须有一个更整洁的LINQ方式来构建它。 有任何想法吗?
List myStrs = someListFromSomewhere; List myInts = new List(); 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; } } }