2012-01-18 21 views
7

私はList<string>を持ち、これらの文字列のいくつかは数値です。このサブセットをList<int>に抽出します。LINQを使用して文字列のリストからintを抽出する

私はこれを非常に冗長な方法で行っています - 以下のように - しかし、私は、これを構造化するための、より洗練されたLINQの方法が必要であると感じています。何か案は?

List<string> myStrs = someListFromSomewhere; 
List<int> myInts = new List<int>(); 

foreach (string myStr in myStrs) 
{ 
    int outInt; 
    if (int.TryParse(myStr, out outInt)) 
    { 
     myInts.Add(outInt); 
    } 
} 

もちろん、私はこれに対する解決策を必要としない - それは私のLINQの教育のために主にです。

+2

私のために別の機会には、「私はTryParseがintを返してほしい?」状態に(私は知っている、遺産...) –

+0

確かに効率的ではありませんが、あなたは 'var myInts = myStrs.Where(s => int.TryParse(s、out outInt))を行うことができます。選択(s => int.Parseあなたがすでに定義されていれば、これは、それぞれの文字列で 'TryParse' *と* Parseを呼び出しますが、私は実際にそれを提案しません。 – rejj

+2

この質問は興味深いかもしれません:[投射を行うLINQクエリ、投射が例外を引き起こすケースをスキップする] http://stackoverflow.com/questions/7188623/linq-query-to-perform-a-projection-skipping-cases-where-the-projection-would-ca)例としてあなたのケースを使用します。 –

答えて

23

あなたはこのようにそれを行うことができます。

int parsed = 0; 

myInts = myStrs.Where(x => int.TryParse(x, out parsed)).Select(x => parsed); 

LINQ演算子の実行が延期されたので、これは意味、働く:に
各項目についてmyStrsWhereでコードが実行され、結果はに書き込まれた最初のparsedTryParsetrueの場合はSelectのコードが実行されます。 1つのアイテムに対するこのコード全体が、このコード全体が次のアイテムのために実行される前に実行されます。

+3

非常に壊れやすいです。 – dtb

+1

@dtb:まったくありません。もしそうなら、あなたはLINQの内部動作を実際に理解していません。 –

+1

ちょうど私の好みのためにLINQの内部の働きについてあまりにも多くの知識が必要だと言っています。 – dtb

7

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

+1 - 正確に私が掲載しようとしていた解決策。 –

+4

絶対過剰です –

+0

これは本当に* downvoteに値するか?それは間違っていませんか? – Yuck

0

を、これはLINQの教育のためにあるので...あなたは本当にこれが唯一のLINQの構文で行うことができる方法を探している場合は、別のオプションをカプセル化するクラスに解析ロジックを移動することです結果と値。

var myInts = from val in myStrs 
      let parserVal = new Parser(val) 
      where parserVal.IsInt 
      select parserVal.Val; 
パーサはこのようなものである

...

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; 
      } 
     } 
} 
関連する問題