LoginSignup
0
0

More than 5 years have passed since last update.

T型のシーケンスを、任意サイズの配列のシーケンスに変える

Posted at

タイトルから内容が分かりにくいですが、次のようなことをします。

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 でデコードすれば目的の文字列が得られます。

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0