Select parsed int, if string was parseable to int
It's still two codelines, but you can shorten up your original a little:
int asInt = 0;
var ints = from str in strings
where Int32.TryParse(str, out asInt)
select asInt;
Since the TryParse already runs at the time of the select, the asInt
variable is populated, so you can use that as your return value - you don't need to parse it again.
If you don't mind your coworkers jumping you in the parking lot there is a way to do this in one true line of linq (no semicolons) ....
strings.Select<string, Func<int,int?>>(s => (n) => int.TryParse(s, out n) ? (int?)n : (int?)null ).Where(λ => λ(0) != null).Select(λ => λ(0).Value);
It isn't practical, but doing this in one statement was far too interesting a challenge to pass up.
I'd probably have this little utility method somewhere (I actually do in my current codebase :-))
public static class SafeConvert
{
public static int? ToInt32(string value)
{
int n;
if (!Int32.TryParse(value, out n))
return null;
return n;
}
}
Then you use this much cleaner LINQ statement:
from str in strings
let number = SafeConvert.ToInt32(str)
where number != null
select number.Value;
It's hard to do that in query syntax, but it's not too bad in lambda syntax:
var ints = strings.Select(str => {
int value;
bool success = int.TryParse(str, out value);
return new { value, success };
})
.Where(pair => pair.success)
.Select(pair => pair.value);
Alternatively, you may find it worth writing a method which returns an int?
:
public static int? NullableTryParseInt32(string text)
{
int value;
return int.TryParse(text, out value) ? (int?) value : null;
}
Then you can just use:
var ints = from str in strings
let nullable = NullableTryParseInt32(str)
where nullable != null
select nullable.Value;