VB.NETで配列を結合する方法!(CopyTo/Concat/Union)

VB.NET

VB.NETでは配列を結合する方法がいくつか用意されており、それぞれの特徴や用途に応じて使い分けることができます。

配列の結合にはいくつかの方法があり、それぞれに特徴と最適な使用場面があります。
特に、結合時に重複要素をどのように扱うかによって、選択すべき方法が変わってきます。

この記事では、VB.NETで配列を結合する主要な方法を複数紹介し、それぞれの使い方などを解説します。

Array.CopyToメソッドで配列を結合する

Array.CopyTo メソッドは、ある配列の要素を別の配列にコピーするために使用します。
これは、既存の配列に別の配列の要素を追加する形で結合する場合に利用できます。

ただし、結合先の配列には十分なスペースが事前に確保されている必要があります。

構文

Public Sub CopyTo(array As Array, index As Integer)
  • array: コピー先の配列。
  • index: コピー先の配列のどこからコピーを開始するかを示すインデックス(0から始まる)。

使用例

CopyToメソッドの使用例です。

Module ArrayCopyToExample
    Sub Main()
        Dim array1 As Integer() = {1, 2, 3}
        Dim array2 As Integer() = {4, 5, 6}

        ' 結合後の配列のサイズを計算し、新しい配列を作成
        Dim combinedLength As Integer = array1.Length + array2.Length
        Dim combinedArray(combinedLength - 1) As Integer

        ' array1 の要素を combinedArray の先頭にコピー
        array1.CopyTo(combinedArray, 0)

        ' array2 の要素を combinedArray の array1 の要素の直後にコピー
        array2.CopyTo(combinedArray, array1.Length)

        Console.Write("結合された配列 (CopyTo): ")
        For Each item In combinedArray
            Console.Write($"{item} ")
        Next
        Console.WriteLine()
        ' 出力: 結合された配列 (CopyTo): 1 2 3 4 5 6
    End Sub
End Module

最初にarray1array2配列を作成しています。

次に、これら2つの配列の要素をすべて格納できるcombinedArrayという新しい配列を、適切なサイズで宣言しています。
array1.CopyTo(combinedArray, 0)で、array1の要素をcombinedArrayの先頭(インデックス0)からコピーします。

続いて、array2.CopyTo(combinedArray, array1.Length)で、array2の要素をcombinedArrayarray1の要素の直後(array1.Lengthの位置)からコピーします。
これにより、array1の要素の後にarray2の要素が続く形で、1つの配列に結合されます。

注意点

  • 新しい配列の事前作成: 結合結果を格納するための新しい配列を、事前に適切なサイズで作成しておく必要があります。
  • インデックスの管理: コピー先のインデックスを正確に管理する必要があります。
  • 型の一致: コピー元とコピー先の配列の型が一致している必要があります。
  • 破壊的ではない: CopyTo は元の配列を変更せず、指定されたコピー先に要素を書き込みます。
  • 重複の扱い: 重複する要素もそのままコピーされます。

LINQのConcatメソッドで配列を結合する(重複を保持)

LINQ (Language Integrated Query) の Concat メソッドは、2つのシーケンス(配列も含む)を連結し、新しいシーケンスを返します。
これは、VB.NETで配列を結合する最も簡潔で推奨される方法の一つです。

Concat は、重複する要素もすべて保持します。

構文

Public Function Concat(Of TSource)(first As IEnumerable(Of TSource), second As IEnumerable(Of TSource)) As IEnumerable(Of TSource)
  • first: 最初のシーケンス。
  • second: 2番目のシーケンス。

使用例

Concatの使用例です。
System.Linq 名前空間をインポートする必要があります。

Imports System.Linq

Module LinqConcatExample
    Sub Main()
        Dim array1 As String() = {"Apple", "Banana"}
        Dim array2 As String() = {"Banana", "Orange"} ' "Banana" は重複

        ' Concat メソッドで2つの配列を結合(重複を保持)
        Dim combinedArray As String() = array1.Concat(array2).ToArray()

        Console.Write("結合された配列 (LINQ Concat - 重複保持): ")
        For Each item In combinedArray
            Console.Write($"{item} ")
        Next
        Console.WriteLine()
        ' 出力: 結合された配列 (LINQ Concat - 重複保持): Apple Banana Banana Orange

        Dim nums1 As Integer() = {10, 20, 30}
        Dim nums2 As Integer() = {30, 40, 50} ' 30 は重複
        Dim combinedNums As Integer() = nums1.Concat(nums2).ToArray()

        Console.Write("結合された数値配列 (LINQ Concat - 重複保持): ")
        For Each item In combinedNums
            Console.Write($"{item} ")
        Next
        Console.WriteLine()
        ' 出力: 結合された数値配列 (LINQ Concat - 重複保持): 10 20 30 30 40 50
    End Sub
End Module

この例では、array1array2という2つの文字列配列を結合しています。

array1.Concat(array2)は、array1の要素の後にarray2の要素を連結した新しいIEnumerable(Of String)(列挙可能なコレクション)を生成します。
この際、”Banana”のように両方の配列に存在する重複要素もそのまま保持されます。

最後に.ToArray()メソッドを呼び出すことで、生成されたIEnumerable(Of String)を通常の配列String()に変換し、combinedArrayに格納しています。
数値配列の例でも同様に、nums1nums2が連結され、重複する30も両方含まれた状態で結合されていることが確認できます。

注意点

  • Imports System.Linq: この名前空間をファイルの先頭に記述する必要があります。
  • ToArray(): Concat メソッドは IEnumerable(Of T) を返すため、結果を配列として利用したい場合は ToArray() メソッドで変換する必要があります。
  • 新しい配列を生成: Concat は常に新しい配列(または IEnumerable(Of T)) を生成し、元の配列は変更しません。
  • 複数配列の結合: 3つ以上の配列を結合する場合は、array1.Concat(array2).Concat(array3).ToArray() のように連続して呼び出すことができます。

LINQのUnionメソッドで配列を結合する(重複を除去)

LINQのUnionメソッドは、2つのシーケンス(配列も含む)を連結し、重複する要素をすべて除去して、新しいシーケンスを返します。
これは、結合後の配列に一意な要素のみを含めたい場合に非常に便利です。

構文

Public Function Union(Of TSource)(first As IEnumerable(Of TSource), second As IEnumerable(Of TSource)) As IEnumerable(Of TSource)
  • first: 最初のシーケンス。
  • second: 2番目のシーケンス。

使用例

Unionの使用例です。
System.Linq 名前空間をインポートする必要があります。

Imports System.Linq

Module LinqUnionExample
    Sub Main()
        Dim array1 As String() = {"Apple", "Banana", "Cherry"}
        Dim array2 As String() = {"Banana", "Orange", "Grape"} ' "Banana" は重複

        ' Union メソッドで2つの配列を結合(重複を除去)
        Dim combinedArray As String() = array1.Union(array2).ToArray()

        Console.Write("結合された配列 (LINQ Union - 重複除去): ")
        For Each item In combinedArray
            Console.Write($"{item} ")
        Next
        Console.WriteLine()
        ' 出力: 結合された配列 (LINQ Union - 重複除去): Apple Banana Cherry Orange Grape

        Dim nums1 As Integer() = {10, 20, 30}
        Dim nums2 As Integer() = {30, 40, 50} ' 30 は重複
        Dim combinedNums As Integer() = nums1.Union(nums2).ToArray()

        Console.Write("結合された数値配列 (LINQ Union - 重複除去): ")
        For Each item In combinedNums
            Console.Write($"{item} ")
        Next
        Console.WriteLine()
        ' 出力: 結合された数値配列 (LINQ Union - 重複除去): 10 20 30 40 50
    End Sub
End Module

この例では、array1array2という2つの文字列配列を結合しています。

array1.Union(array2)は、両方の配列の要素を連結しますが、重複する要素(この場合は”Banana”)は1つだけになるように除去します。
その後、.ToArray()メソッドで結果を配列に変換し、combinedArrayに格納しています。

数値配列の例でも同様に、nums1nums2が連結され、重複する「30」は1つだけ含まれた状態で結合されていることが確認できます。

注意点

  • Imports System.Linq: この名前空間をファイルの先頭に記述する必要があります。
  • ToArray(): Union メソッドは IEnumerable(Of T) を返すため、結果を配列として利用したい場合は ToArray() メソッドで変換する必要があります。
  • 新しい配列を生成: Union は常に新しい配列(または IEnumerable(Of T)) を生成し、元の配列は変更しません。
  • 重複の除去: 結合元の両方の配列に存在する重複要素は、結果の配列では1つだけになります。
  • 要素の順序: Union メソッドによって返される要素の順序は、元のシーケンスの順序と異なる場合があります。特に、重複が除去されるため、元の順序が完全に保持される保証はありません。

Listを利用して配列を結合する

List(Of T) クラスは、動的なサイズ変更が可能なコレクションであり、配列の結合にも非常に柔軟に対応できます。
特に、複数の配列を順不同で追加したり、後から要素を追加・削除したりする可能性がある場合に便利です。

構文

List(Of T) オブジェクトを作成し、AddRange メソッドを使用して配列の要素を追加します。

Dim myList As New List(Of T)()
myList.AddRange(array1)
myList.AddRange(array2)

使用例

List(Of T)を利用した結合例です。

Module ListCombineExample
    Sub Main()
        Dim arrayA As String() = {"ItemA", "ItemB"}
        Dim arrayB As String() = {"ItemC", "ItemD"}
        Dim arrayC As String() = {"ItemE"}

        ' List(Of String) を作成
        Dim combinedList As New List(Of String)()

        ' 各配列の要素をリストに追加
        combinedList.AddRange(arrayA)
        combinedList.AddRange(arrayB)
        combinedList.AddRange(arrayC)

        Console.Write("結合されたリスト (List(Of T)): ")
        For Each item In combinedList
            Console.Write($"{item} ")
        Next
        Console.WriteLine()
        ' 出力: 結合されたリスト (List(Of T)): ItemA ItemB ItemC ItemD ItemE

        ' 必要であれば、リストを配列に変換
        Dim finalArray As String() = combinedList.ToArray()
        Console.Write("リストから変換された配列: ")
        For Each item In finalArray
            Console.Write($"{item} ")
        Next
        Console.WriteLine()
        ' 出力: リストから変換された配列: ItemA ItemB ItemC ItemD ItemE
    End Sub
End Module

この例では、arrayAarrayBarrayCという3つの配列の要素を結合しています。

まず、List(Of String)型のcombinedListという新しいリストを作成します。
次に、combinedList.AddRange(arrayA)のように、各配列をAddRangeメソッドを使ってcombinedListに追加していきます。
AddRangeは指定されたコレクションのすべての要素をリストの末尾に追加します。

これにより、すべての配列の要素がcombinedListに順序通り追加され、1つのリストとして結合されます。
最後に、必要に応じてcombinedList.ToArray()を呼び出すことで、このリストを通常の配列String()に変換し、finalArrayに格納しています。

注意点

  • List(Of T) オブジェクトの作成: 一時的に List(Of T) オブジェクトを作成する必要があります。
  • ToArray() で配列に変換: 最終的に配列として利用したい場合は、ToArray() メソッドで変換する必要があります。
  • 柔軟性: List(Of T) は、要素の追加・削除が容易なため、結合後にさらに操作が必要な場合に非常に便利です。
  • パフォーマンス: 非常に大規模な配列を大量に結合する場合、List(Of T) の動的なサイズ変更がオーバーヘッドになる可能性がありますが、ほとんどの一般的なシナリオでは問題ありません。
  • 重複の扱い: AddRange は重複する要素もそのまま追加します。結合後に重複を除去したい場合は、combinedList.Distinct().ToArray() のように Distinct() メソッドを別途適用する必要があります。

まとめ

VB.NETで配列を結合する方法はいくつかあり、それぞれの目的に応じて最適な選択肢が異なります。

  • 結合先の配列サイズが固定で、インデックスを直接管理したい場合: Array.CopyTo メソッド
  • 複数の配列を連結して新しい配列を生成し、重複する要素もすべて保持したい場合(最も簡潔な方法の一つ): LINQの Concat メソッド
  • 複数の配列を連結して新しい配列を生成し、重複する要素をすべて除去して一意な要素のみを含めたい場合: LINQの Union メソッド
  • 結合後に要素の追加・削除など、柔軟な操作が必要な場合: List(Of T) を利用

これらの方法を理解し、状況に応じて使い分けることで、VB.NETでの配列操作を効率的かつ堅牢に行うことができます。

コメント