VB で LINQ で連番
Enumerable.Range 使うと簡単にできるみたい。
Module Module1 Sub Main() Dim numbers = From n In Enumerable.Range(1, 100) Select n * n ' メソッド構文 ' Dim numbers = Enumerable.Range(1, 100).Select(Function(n) n * n) For Each number In numbers Console.WriteLine(number) Next Console.ReadLine() End Sub End Module
結果
1 4 9 ・・・(中略)・・・ 9604 9801 10000
#TL で突っ込み頂いたので書き直しました(汗
そもそもの発端
下記のコードを LINQ で書き換えられないか考えていたところ、たまたま TL に LINQ の話が流れてたのでチャレンジしたいと思いました。
command.Parameters.AddWithValue("pattern1", checkCollection(0).Id) command.Parameters.AddWithValue("pattern2", checkCollection(1).Id) command.Parameters.AddWithValue("pattern3", checkCollection(2).Id) command.Parameters.AddWithValue("pattern4", checkCollection(3).Id) command.Parameters.AddWithValue("pattern5", checkCollection(4).Id)
コレクション「checkCollection」のアイテムが5個に満たないケースが発生したため、修正が発生しました。
For i = 0 To 4 command.Parameters.AddWithValue(String.Format("pattern{0}", i + 1), -1) Next Dim j = 0 For Each ch In checkCollection command.Parameters(j).Value = ch.Id j += 1 Next
For 〜For Each 文が連続して書いてあるのを見ると、どうにも LINQ に置き換えたくなります。LINQ 星人じゃないので、LINQ で連番どうやって実装するか少し頭を使いましたが、Enumerable.Range を使えばいいと知り、まず上の For 文だけでも LINQ に変更してみます。
Dim c = From n In Enumerable.Range(1, 5) Select New MySqlParameter(String.Format("pattern{0}", n), -1) command.Parameters.AddRange(c.ToArray()) Dim i = 0 For Each ch In checkCollection command.Parameters(i).Value = ch.Id i += 1 Next
ただしまだ美しくないですね。下に残ってる For Each も一つのクエリで纏めたいです。
クエリ構文じゃ限界ぽいので、メソッド構文で対応してみました。
Dim c = Enumerable.Range(1, 5).Select( Function(number) As MySqlParameter Dim ret = New MySqlParameter(String.Format("pattern{0}", number), -1) If (number < checkCollection.Count) Then ret.Value = number End If Return ret End Function) command.Parameters.AddRange(c.ToArray())
C# の構文に比べるとかなり冗長感ありますが、まあこれで解決ということで。