Using type in linq

Possible duplicate:
LINQ: select int parsing if the string was subject to int parsing

This may be the main question, but I could not figure out the work. I have an array of strings and I tried to parse them with integers. As expected, I got exception formatting.

How can I skip "3a" and continue parsing the remaining array and storing integers in the output using Linq.? Is this the best approach or practice DO DO DO DO? Pls shed some light on how to use TryParse in this case

using System; using System.Collections.Generic; using System.Linq; using System.Text; namespace ConsoleApplication1 { class Program { static void Main(string[] args) { string[] values = { "1", "2", "3a","4" }; List<int> output = new List<int>(); try{ output = values.Select(i => int.Parse(i)).ToList<int>(); } catch(FormatException) { foreach (int i in output) Console.WriteLine(i); } foreach (int i in output) Console.WriteLine(i); Console.ReadLine(); } } } 
+7
source share
6 answers

You can use int.TryParse

 string[] values = { "1", "2", "3a","4" }; int i = int.MinValue; List<int> output = values.Where(s => int.TryParse(s, out i)) .Select(s => i) .ToList(); 

Demo

However, Eric Lippert will not be surprised . Therefore, if you do not want to (ab) use side effects, this will be the best approach:

Create an extension method, for example:

 public static class NumericExtensions { public static int? TryGetInt(this string item) { int i; bool success = int.TryParse(item, out i); return success ? (int?)i : (int?)null; } } 

Then you can write this:

 List<int> output = values.Select(s => s.TryGetInt()) .Where(nullableInt => nullableInt.HasValue) .Select(nullableInt => nullableInt.Value) .ToList(); 
+7
source

Although I totally agree with the int.TryParse answer in Tim Schmelter's answer, I think his answer is based on an undocumented implementation detail, and a safer alternative could be

 List<int> output = values .Select(s => { int i; return int.TryParse(s, out i) ? i : default(int?); }) .Where(i => i != null) .Select(i => i.Value) .ToList(); 

Maybe you replace .Where(...).Select(...) with .OfType<int>() .

You can also put the first .Select(...) lambda with an explicit reusable function:

 int? MyTryParse(string s) { int i; return int.TryParse(s, out i) ? i : default(int?); } List<int> output = values .Select(MyTryParse) .Where(i => i != null) .Select(i => i.Value) .ToList(); 
+2
source

linq version from Tim Shmelter answer

  string[] values = { "1", "2", "3a", "4" }; int i = int.MinValue; var output = (from c in values where int.TryParse(c, out i) select c).Select(s => int.Parse(s)).ToList(); foreach (var item in output) { Console.WriteLine(item.ToString()); } 
+2
source

Why do you want to use LINQ?

Try the following:

 foreach(string str in values) { int val; if(int.TryParse(str, out val)) { output.Add(val); } } 
+1
source

How about this? Inspired by Tim's answer, but with a temporary variable moved inside the loop, so it is parallel (suppose the collections of values string were ParallelEnumerable).

 values.Select(s => {int i; return int.TryParse(s, out i) ? (int?)i : null;}) .Where(x=>x!=null).Select(x=>x.Value); 

So, the given ["1", "two", "3"] returns [1,3]

+1
source
 List<string> output = values.Where(v => Regex.Match(v, "^(0|[1-9][0-9]*)$").Success) .ToList(); 

An example of using Regex for more control is to determine which values โ€‹โ€‹should be considered valid.

0
source

All Articles