使用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; } } }