7

重複の可能性:
LINQ:文字列がintに解析可能である場合は、解析されたintを選択します

これは基本的な質問かもしれませんが、回避策を見つけることができませんでした。文字列の配列があり、整数で解析しようとしました。予想通り、フォーマット例外が発生しました。

「3a」をスキップして、残りの配列の解析を続行し、Linqを使用して整数を出力に格納するにはどうすればよいですか?これはより良いアプローチですか、それとも実践しないでください。この場合、PlsはTryParseの使用方法に光を当てます

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();
        }

    }
}
4

6 に答える 6

7

使用できます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();

デモ

ただし、EricLippertは面白がっていません。したがって、副作用を(乱用)したくない場合は、これがベストプラクティスのアプローチになります。

次のような拡張メソッドを作成します。

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

次に、これを書くことができます:

List<int> output = values.Select(s => s.TryGetInt())
             .Where(nullableInt => nullableInt.HasValue)
             .Select(nullableInt => nullableInt.Value)
             .ToList();
于 2013-01-22T13:10:14.633 に答える
2

TimSchmelterの回答からのlinqバージョン

        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());
        }
于 2013-01-22T13:37:58.140 に答える
2

int.TryParse私はTimSchmelterの回答での使用に完全に同意しますが、彼の回答は文書化されていない実装の詳細に依存していると思います。より安全な代替案は

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();

.Where(...).Select(...)をで置き換えることができる場合があります.OfType<int>()

明示的に再利用可能な関数を使用して最初の.Select(...)ラムダを配置することもできます。

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();
于 2013-01-22T13:25:29.087 に答える
1

なぜLINQを使いたいのですか?

これを試して:

foreach(string str in values)
{
   int val;
   if(int.TryParse(str, out val))
   {
      output.Add(val);
   }
}
于 2013-01-22T13:17:23.467 に答える
1

これはどう?ティムの答えに触発されましたが、一時変数がループ内に移動したため、並列で安全です(文字列のコレクションがvaluesParallelEnumerableであると仮定します)。

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

だから["1", "two", "3"]それが戻ると[1,3]

于 2013-01-22T13:29:54.163 に答える
0
List<string> output = values.Where(v => Regex.Match(v, "^(0|[1-9][0-9]*)$").Success)
                                        .ToList();

どの値が有効であると見なされるかを指示するためのより詳細な制御のために正規表現を使用する例。

于 2013-01-22T13:20:38.907 に答える