タイトルから内容が分かりにくいですが、次のようなことをします。
For Each a In Enumerable.Range(1, 10).Buffer(5)
For Each b In a
Console.Write("{0} ", b)
Next
Console.WriteLine()
Next
を実行すると
1 2 3 4 5
6 7 8 9 10
と表示されます。で、タイトルの内容を処理するのが Buffer()
です。
IEnumerable(Of T) に拡張メソッドを追加しています。
ソースコードを次に示します。
Buffer.vb
Module EnumerableExBuffer
<Extension>
Public Function Buffer(Of T)(
ByVal source As IEnumerable(Of T),
ByVal count As Integer
) As IEnumerable(Of T())
If source Is Nothing Then Throw New ArgumentNullException("source")
If count < 1 Then Throw New ArgumentOutOfRangeException("count")
Return Buffer_(source, count)
End Function
Private Iterator Function Buffer_(Of T)(
ByVal source As IEnumerable(Of T),
ByVal count As Integer
) As IEnumerable(Of T())
Dim list = New List(Of T)(count)
For Each item In source
list.Add(item)
If list.Count = count Then
Yield list.ToArray()
list.Clear()
End If
Next
If list.Count > 0 Then
Yield list.ToArray()
End If
End Function
End Module
実際にはどんな使い方があるかというと、一例で、文字列"414243444546"を"ABCDEF"に変換するときに
Dim s = Encoding.ASCII.GetString(
"414243444546"
.Buffer(2)
.Select(Function(a) New String(a))
.Select(Function(a) Convert.ToByte(a, 16))
.ToArray())
と書ける。文字列は IEnumerable(Of Char)
に変換できるので、.Buffer(2)
で 2文字の配列のシーケンスにします。その後、Char の配列から文字列を作成し、Convert.ToByte で16進文字列をバイトに変換し、最後にバイト配列にしています。作成されたバイト配列を ASCII でデコードすれば目的の文字列が得られます。