共用方式為


Visual Basic 中的陣列

陣列是一組稱為「 元素」的值,這些值在邏輯上彼此相關。 例如,陣列可能包含文法學校中每個年級的學生數目;數位的每個元素都是單一年級的學生數目。 同樣地,陣列可能包含學生的班級成績;陣列的每個元素都是單一等級。

您可以使用個別變數來儲存我們的每個資料項。 例如,如果我們的應用程式分析學生成績,我們可以針對每個學生的成績使用不同的變數,例如 englishGrade1englishGrade2等。此方法有三個主要限制:

  • 我們必須在設計階段確切知道需要處理多少個年級。
  • 處理大量成績很快就會變得繁瑣。 這反過來又讓應用程式更有可能有嚴重的 Bug。
  • 很難維持。 我們新增的每個新等級都需要修改、重新編譯和重新部署應用程式。

藉由使用陣列,您可以以相同名稱來參照這些相關值,並使用稱為 索引下標 的數字,根據其在陣列中的位置來識別個別元素。 陣列的索引範圍從0到陣列中元素總數減一。 當您使用 Visual Basic 語法定義陣列大小時,您指定的是最高索引,而不是陣列的元素總數。 您可以將陣列當作一個單位使用,並且可以迭代其元素,使您在設計時不必知道確切包含多少個元素。

說明前的一些快速範例:

' Declare a single-dimension array of 5 numbers.
Dim numbers(4) As Integer

' Declare a single-dimension array and set its 4 values.
Dim numbers = New Integer() {1, 2, 4, 8}

' Change the size of an existing array to 16 elements and retain the current values.
ReDim Preserve numbers(15)

' Redefine the size of an existing array and reset the values.
ReDim numbers(15)

' Declare a 6 x 6 multidimensional array.
Dim matrix(5, 5) As Double

' Declare a 4 x 3 multidimensional array and set array element values.
Dim matrix = New Integer(,) {{1, 2, 3}, {2, 3, 4}, {3, 4, 5}, {4, 5, 6}}

' Declare a jagged array
Dim sales()() As Double = New Double(11)() {}

簡單陣列中的陣列元素

讓我們建立名為 students 的陣列,以儲存文法學校中每個年級的學生數目。 元素的索引範圍從 0 到 6。 使用此陣列比宣告七個變數更簡單。

下圖顯示 students 陣列。 針對陣列的每個元素:

  • 元素的索引代表年級 (索引 0 代表幼稚園)。

  • 元素中包含的值代表該年級的學生數目。

顯示學生數目陣列的圖表

下列範例包含建立及使用 陣列的 Visual Basic 程式代碼:


Module SimpleArray
   Public Sub Main()
      ' Declare an array with 7 elements.
      Dim students(6) As Integer

      ' Assign values to each element.
      students(0) = 23
      students(1) = 19
      students(2) = 21
      students(3) = 17
      students(4) = 19
      students(5) = 20
      students(6) = 22
      
      ' Display the value of each element.
      For ctr As Integer = 0 To 6
         Dim grade As String = If(ctr = 0, "kindergarten", $"grade {ctr}")
         Console.WriteLine($"Students in {grade}: {students(ctr)}")
      Next
   End Sub
End Module
' The example displays the following output:
'     Students in kindergarten: 23
'     Students in grade 1: 19
'     Students in grade 2: 21
'     Students in grade 3: 17
'     Students in grade 4: 19
'     Students in grade 5: 20
'     Students in grade 6: 22

此範例會執行三件事:

  • 它會宣告具有七個元素的 students 陣列。 陣列宣告中的數位 6 表示陣列中的最後一個索引;它是小於陣列中的元素數目。
  • 它會將值指派給陣列中的每個元素。 要存取陣列元素,使用陣列名稱,並在括號中包含個別元素的索引。
  • 它會列出陣列的每個值。 此範例會使用 For 語句,依其索引編號來存取陣列的每個元素。

students上述範例中的陣列是一維數位列,因為它使用一個索引。 使用多個索引或下標的陣列稱為 多維度。 如需詳細資訊,請參閱本文的其餘部分和 Visual Basic中的陣組維度

建立陣列

您可以透過多種方式定義陣列的大小:

  • 您可以在宣告陣列時指定大小:

    ' Declare an array with 10 elements.
    Dim cargoWeights(9) As Double               
    ' Declare a 24 x 2 array.
    Dim hourlyTemperatures(23, 1) As Integer
    ' Declare a jagged array with 31 elements.
    Dim januaryInquiries(30)() As String
    
  • 您可以在建立陣列時使用 New 子句來指定陣列的大小。

    ' Declare an array with 10 elements.
    Dim cargoWeights() As Double = New Double(9) {}
    ' Declare a 24 x 2 array.
    Dim hourlyTemperatures(,) As Integer = New Integer(23, 1) {}
    ' Declare a jagged array with 31 elements. 
    Dim januaryInquiries()() As String = New String(30)() {}
    

如果您有現有的陣列,您可以使用 語句重新定義其大小 ReDim 。 您可以指定 語句保留 ReDim 陣列中的值,也可以指定它建立空陣列。 下列範例展示不同方法使用ReDim語句,以修改現有陣列的大小。

' Assign a new array size and retain the current values.
ReDim Preserve cargoWeights(20)
' Assign a new array size and retain only the first five values.
ReDim Preserve cargoWeights(4)
' Assign a new array size and discard all current element values.
ReDim cargoWeights(15)

如需詳細資訊,請參閱 ReDim 語句

將值儲存在陣列中

您可以使用 類型的 Integer索引來存取陣列中的每個位置。 您可以使用小括號括住的索引來引用陣列中的每個位置,從而儲存和擷取值。 多維度陣列的索引會以逗號 (,) 分隔。 每個陣列維度都需要一個索引。

下列範例顯示一些語句,這些語句會儲存和擷取數位列中的值。


Module Example
   Public Sub Main()
      ' Create a 10-element integer array.
      Dim numbers(9) As Integer
      Dim value As Integer = 2
        
      ' Write values to it.
      For ctr As Integer = 0 To 9
         numbers(ctr) = value
         value *= 2
      Next
        
      ' Read and sum the array values.  
      Dim sum As Integer
      For ctr As Integer = 0 To 9
         sum += numbers(ctr)
      Next
      Console.WriteLine($"The sum of the values is {sum:N0}")
    End Sub
End Module
' The example displays the following output:
'     The sum of the values is 2,046

使用陣列字面值填入陣列

藉由使用陣列常值,您可以在建立陣列時填入一組初始值。 陣列字面值由大括弧括住的逗號分隔值列表所組成。

當您使用陣列常值建立陣列時,您可以提供陣列類型或使用類型推斷來確定陣列類型。 下列範例顯示這兩個選項。

' Array literals with explicit type definition.
Dim numbers = New Integer() {1, 2, 4, 8}
' Array literals with type inference.
Dim doubles = {1.5, 2, 9.9, 18}
' Array literals with explicit type definition.
Dim articles() As String = { "the", "a", "an" }

' Array literals with explicit widening type definition.
Dim values() As Double = { 1, 2, 3, 4, 5 }

當您使用類型推斷時,陣列的類型是由常值清單中 的主要類型 所決定。 主要類型是陣列中所有其他類型可以擴大的類型。 如果無法判斷此唯一類型,則主控類型是陣列中所有其他類型可以縮小的唯一類型。 如果這兩個唯一類型都無法判斷,則主要類型為 Object。 例如,如果提供給陣列常值的值清單包含類型IntegerLongDouble的值,則產生的陣列是類型Double。 因為 IntegerLong 只會擴大為 DoubleDouble 是主要類型。 如需詳細資訊,請參閱 擴大和縮小轉換

備註

您只能針對類型成員中定義為局部變數的陣列使用類型推斷。 如果沒有明確的型別定義,則在類別層級使用陣列常值定義的陣列其型別為 Object[]。 如需詳細資訊,請參閱 本機類型推斷

請注意,儘管所有陣列常值都屬於values類型,前一個範例仍將Double定義為類型Integer的陣列。 您可以建立此陣列,因為陣列常值中的值可以擴大為 Double 值。

您也可以使用 巢狀陣列常值來建立和填入多維度陣列。 巢狀陣列常值必須有與結果陣列尺寸一致的維度數量。 下列範例會使用巢狀陣列常值建立整數的二維陣列。

' Create and populate a 2 x 2 array.
Dim grid1 = {{1, 2}, {3, 4}}
' Create and populate a 2 x 2 array with 3 elements.
Dim grid2(,) = {{1, 2}, {3, 4}, {5, 6}}

使用巢狀陣列常值來建立和填入陣列時,如果巢狀陣列常值中的元素數目不相符,就會發生錯誤。 如果您明確宣告陣列變數的維度數目與陣列常值不同,也會發生錯誤。

就像您可以針對一維陣列一樣,在建立具有巢狀陣列常值的多維度陣列時,您可以依賴類型推斷。 推斷的類型在所有巢狀層級的陣列常數中都是主導類型。 下列範例會從型別Double[,]Integer的值建立類型為Double的二維陣列。

Dim arr = {{1, 2.0}, {3, 4}, {5, 6}, {7, 8}}

如需其他範例,請參閱 如何:在Visual Basic中初始化數位變數

逐一查看陣列

當您逐一查看陣列時,您會從最低索引存取陣列中的每個元素,或從最高到最低。 一般而言,請使用 For...Next 語句For Each...Next 語句逐一遍歷陣列中的元素。 當您不知道陣列的上限時,您可以呼叫 Array.GetUpperBound 方法以取得索引的最高值。 雖然最低索引值幾乎一律為 0,但您可以呼叫 Array.GetLowerBound 方法來取得索引的最低值。

下列範例會使用 For...Next 語句逐一查看一維陣列。


Module IterateArray
   Public Sub Main()
      Dim numbers = {10, 20, 30}

      For index = 0 To numbers.GetUpperBound(0)
         Console.WriteLine(numbers(index))
      Next
   End Sub
End Module
' The example displays the following output:
'  10
'  20
'  30

下列範例會使用 For...Next 語句逐一查看多維度陣列。 方法 GetUpperBound 具有指定維度的參數。 GetUpperBound(0) 會傳回第一個維度的最高索引,並 GetUpperBound(1) 傳回第二個維度的最高索引。


Module IterateArray
   Public Sub Main()
      Dim numbers = {{1, 2}, {3, 4}, {5, 6}}

      For index0 = 0 To numbers.GetUpperBound(0)
         For index1 = 0 To numbers.GetUpperBound(1)
            Console.Write($"{numbers(index0, index1)} ")
         Next
         Console.WriteLine()
      Next
   End Sub
End Module
' The example displays the following output:
' Output 
'  1 2 
'  3 4 
'  5 6

下列範例使用 For Each...Next 語句,逐一查看一維數位列和二維陣列。


Module IterateWithForEach
   Public Sub Main()
      ' Declare and iterate through a one-dimensional array.
      Dim numbers1 = {10, 20, 30}
      
      For Each number In numbers1
         Console.WriteLine(number)
      Next
      Console.WriteLine()
      
      Dim numbers = {{1, 2}, {3, 4}, {5, 6}}

      For Each number In numbers
         Console.WriteLine(number)
      Next
   End Sub
End Module
' The example displays the following output:
'  10
'  20
'  30
'
'  1
'  2
'  3
'  4
'  5
'  6

陣列大小

陣列的大小是其所有維度長度的乘積。 它代表陣列中目前所包含的項目總數。 例如,下列範例會宣告每個維度中有四個元素的 2 維陣列。 如範例的輸出所示,陣列的大小為 16 (或 (3 + 1) * (3 + 1)。


Module Example
   Public Sub Main()
      Dim arr(3, 3) As Integer
      Console.WriteLine(arr.Length)     
   End Sub
End Module
' The example displays the following output:
'     16

備註

關於陣列大小的討論不適用於鋸齒陣列。 如需有關不規則陣列和判斷不規則陣列大小的資訊,請參閱 Jagged arrays 節。

您可以使用 屬性來尋找陣列 Array.Length 的大小。 您可以使用 方法,找到多維度陣列 Array.GetLength 的每個維度長度。

您可以將新的陣列物件指派給陣列變數,或使用 ReDim 語句來調整陣列變數的大小。 下列範例會 ReDim 使用 語句,將 100 元素陣列變更為 51 元素陣列。


Module Example
   Public Sub Main()
      Dim arr(99) As Integer
      Console.WriteLine(arr.Length)
      
      Redim arr(50)
      Console.WriteLine(arr.Length)
   End Sub
End Module
' The example displays the following output:
'     100
'     51

 

當處理陣列的大小時,有幾件事情需要注意。

註釋
維度長度 每個維度的索引是以0為基礎,這表示其範圍從0到其上限。 因此,指定維度的長度大於該維度的宣告上限。
長度限制 陣列每個維度的長度限制為數據類型的 Integer 最大值,也就是 Int32.MaxValue 或 (2 ^ 31) - 1。 不過,陣列的總大小也會受限於系統上可用的記憶體。 如果您嘗試初始化一個超出可用記憶體的陣列,執行階段會擲回OutOfMemoryException
大小和元素大小 陣列的大小與其元素的數據類型無關。 大小一律代表元素總數,而不是它們在記憶體中取用的位元元組數目。
記憶體耗用量 對於陣列儲存在記憶體中的方式沒有任何假設是不安全的。 儲存空間因不同資料寬度的平臺而有所不同,因此在 64 位元系統上,相同的陣列可能會比在 32 位元系統上耗用更多的記憶體。 根據初始化陣列時的系統組態而定,Common Language Runtime (CLR) 可以指派記憶體,以盡可能將元素封裝在一起,或將它們全部對齊在自然硬體界限上。 此外,陣列需要存儲額外開銷來管理控制信息,而且每增加一個維度都會增加此額外開銷。

陣列類型

每個陣列都有數據類型,其數據類型與其元素的數據類型不同。 所有陣列都沒有單一數據類型。 相反地,陣列的數據類型取決於陣列中元素的維度數目或 排名,以及陣列中元素的數據類型。 只有當兩個數位變數具有相同的順位,且其元素具有相同的數據類型時,兩個數位變數才屬於相同的數據類型。 陣列維度的長度不會影響數位資料類型。

每個陣列都會繼承自 System.Array 類別,而且您可以將變數宣告為類型 Array,但無法建立 型別 Array的陣列。 例如,雖然下列程式代碼會將 arr 變數宣告為 型 Array 別,並呼叫 Array.CreateInstance 方法來具現化數位列,但陣列的類型證明為 Object[]。


Module Example
   Public Sub Main()
      Dim arr As Array = Array.CreateInstance(GetType(Object), 19)
      Console.WriteLine(arr.Length)
      Console.WriteLine(arr.GetType().Name)
   End Sub
End Module
' The example displays the following output:
'     19
'     Object[]

此外, ReDim 語句 無法在宣告為 類型的 Array變數上運作。 基於這些原因,以及確保類型安全,建議將每個陣列宣告為特定類型。

您可以透過數種方式找出陣列或其元素的資料類型。

  • 您可以在變數上呼叫 GetType 方法,以取得 Type 代表變數運行時間類型的物件。 Type物件會在其屬性和方法中保存廣泛的資訊。
  • 您可以將變數傳遞至 TypeName 函式,以取得具有執行時間類型名稱的 String

下列範例會呼叫 GetType 方法與 TypeName 函式,以判斷陣列的類型。 陣列型態為 Byte(,)。 請注意, Type.BaseType 屬性也表示位元組陣列的基底類型是 Array 類別。


Module Example
   Public Sub Main()
      Dim bytes(9,9) As Byte
      Console.WriteLine($"Type of {nameof(bytes)} array: {bytes.GetType().Name}")
      Console.WriteLine($"Base class of {nameof(bytes)}: {bytes.GetType().BaseType.Name}")
      Console.WriteLine()
      Console.WriteLine($"Type of {nameof(bytes)} array: {TypeName(bytes)}")
   End Sub
End Module
' The example displays the following output:
' Type of bytes array: Byte[,]
' Base class of bytes: Array
' 
' Type of bytes array: Byte(,)


作為返回值和參數的陣列

若要從 Function 程式傳回陣列,請將數位資料類型和維度數目指定為 Function 語句的傳回型別。 在函式中,宣告具有相同數據類型和維度數目的局部數位變數。 在 Return 語句中,包含不含括弧的局部數位變數。

若要將陣列指定為 或 Sub 程式的參數Function,請將 參數定義為具有指定資料類型和維度數目的陣列。 在對程式的呼叫中,傳遞具有相同數據類型和維度數目的數位變數。

在下列範例中,GetNumbers 函數會傳回一個類型為 Integer() 的一維陣列 Integer。 程式 ShowNumbers 接受自 Integer() 變數。


Module ReturnValuesAndParams
   Public Sub Main()
      Dim numbers As Integer() = GetNumbers()
      ShowNumbers(numbers)
   End Sub

   Private Function GetNumbers() As Integer()
      Dim numbers As Integer() = {10, 20, 30}
      Return numbers
   End Function

   Private Sub ShowNumbers(numbers As Integer())
      For index = 0 To numbers.GetUpperBound(0)
         Console.WriteLine($"{numbers(index)} ")
      Next
   End Sub
End Module
' The example displays the following output:
'   10
'   20
'   30
    

在下列範例中,GetNumbersMultiDim 函式會傳回一個類型為 Integer(,) 的二維陣列 Integer。 程式 ShowNumbersMultiDim 接受自 Integer(,) 變數。


Module Example
   Public Sub Main()
      Dim numbers As Integer(,) = GetNumbersMultidim()
      ShowNumbersMultidim(numbers)
   End Sub

   Private Function GetNumbersMultidim() As Integer(,)
      Dim numbers As Integer(,) = {{1, 2}, {3, 4}, {5, 6}}
      Return numbers
   End Function

   Private Sub ShowNumbersMultidim(numbers As Integer(,))
      For index0 = 0 To numbers.GetUpperBound(0)
         For index1 = 0 To numbers.GetUpperBound(1)
            Console.Write($"{numbers(index0, index1)} ")
         Next
         Console.WriteLine()
      Next
   End Sub
End Module
' The example displays the following output:
'     1 2
'     3 4
'     5 6

不規則陣列

有時候應用程式中的數據結構是二維,但不是矩形。 例如,您可以使用陣列來儲存每個月每日高溫的資料。 陣列的第一個維度代表月份,但第二個維度代表天數,而月份中的天數則不一致。 鋸齒狀陣列,也稱為陣列的陣列,是針對這類案例所設計。 鋸齒狀陣列是一個陣列,其元素也是陣列。 鋸齒狀陣列和不規則陣列中的每個元素都可以有一或多個維度。

下列範例使用一個包含月份的陣列,其中每個元素都是一個包含每天的陣列。 此範例使用不規則陣列,因為不同月份的天數不同。 此範例示範如何建立不規則陣列、為其指派值,以及擷取和顯示其值。

Imports System.Globalization

Module JaggedArray
   Public Sub Main()
      ' Declare the jagged array of 12 elements. Each element is an array of Double.
      Dim sales(11)() As Double
      ' Set each element of the sales array to a Double array of the appropriate size.
      For month As Integer = 0 To 11
         ' The number of days in the month determines the appropriate size.
         Dim daysInMonth As Integer =
            DateTime.DaysInMonth(Year(Now), month + 1)
         sales(month) = New Double(daysInMonth - 1) {}
      Next 

      ' Store values in each element.
      For month As Integer = 0 To 11
         For dayOfMonth = 0 To sales(month).GetUpperBound(0)
            sales(month)(dayOfMonth) = (month * 100) + dayOfMonth
         Next
      Next

      ' Retrieve and display the array values.
      Dim monthNames = DateTimeFormatInfo.CurrentInfo.AbbreviatedMonthNames
      ' Display the month names.
      Console.Write("    ")
      For ctr = 0 To sales.GetUpperBound(0)
         Console.Write($" {monthNames(ctr)}   ")
      Next   
      Console.WriteLine()
      ' Display data for each day in each month.
      For dayInMonth = 0 To 30
         Console.Write($"{dayInMonth + 1,2}.  ")
         For monthNumber = 0 To sales.GetUpperBound(0)
            If dayInMonth > sales(monthNumber).GetUpperBound(0) Then 
               Console.Write("       ")
            Else
               Console.Write($"{sales(monthNumber)(dayInMonth),-5}  ")
            End If
         Next   
         Console.WriteLine()
      Next
   End Sub
End Module
' The example displays the following output:
'      Jan    Feb    Mar    Apr    May    Jun    Jul    Aug    Sep    Oct    Nov    Dec
'  1.  0      100    200    300    400    500    600    700    800    900    1000   1100
'  2.  1      101    201    301    401    501    601    701    801    901    1001   1101
'  3.  2      102    202    302    402    502    602    702    802    902    1002   1102
'  4.  3      103    203    303    403    503    603    703    803    903    1003   1103
'  5.  4      104    204    304    404    504    604    704    804    904    1004   1104
'  6.  5      105    205    305    405    505    605    705    805    905    1005   1105
'  7.  6      106    206    306    406    506    606    706    806    906    1006   1106
'  8.  7      107    207    307    407    507    607    707    807    907    1007   1107
'  9.  8      108    208    308    408    508    608    708    808    908    1008   1108
' 10.  9      109    209    309    409    509    609    709    809    909    1009   1109
' 11.  10     110    210    310    410    510    610    710    810    910    1010   1110
' 12.  11     111    211    311    411    511    611    711    811    911    1011   1111
' 13.  12     112    212    312    412    512    612    712    812    912    1012   1112
' 14.  13     113    213    313    413    513    613    713    813    913    1013   1113
' 15.  14     114    214    314    414    514    614    714    814    914    1014   1114
' 16.  15     115    215    315    415    515    615    715    815    915    1015   1115
' 17.  16     116    216    316    416    516    616    716    816    916    1016   1116
' 18.  17     117    217    317    417    517    617    717    817    917    1017   1117
' 19.  18     118    218    318    418    518    618    718    818    918    1018   1118
' 20.  19     119    219    319    419    519    619    719    819    919    1019   1119
' 21.  20     120    220    320    420    520    620    720    820    920    1020   1120
' 22.  21     121    221    321    421    521    621    721    821    921    1021   1121
' 23.  22     122    222    322    422    522    622    722    822    922    1022   1122
' 24.  23     123    223    323    423    523    623    723    823    923    1023   1123
' 25.  24     124    224    324    424    524    624    724    824    924    1024   1124
' 26.  25     125    225    325    425    525    625    725    825    925    1025   1125
' 27.  26     126    226    326    426    526    626    726    826    926    1026   1126
' 28.  27     127    227    327    427    527    627    727    827    927    1027   1127
' 29.  28            228    328    428    528    628    728    828    928    1028   1128
' 30.  29            229    329    429    529    629    729    829    929    1029   1129
' 31.  30            230           430           630    730           930           1130

上一個範例使用 For...Next 迴圈,將值逐一指派給鋸齒陣列的元素。 您也可以使用巢狀陣列常值來為鋸齒狀陣列的元素指派值。 不過,嘗試使用巢狀陣列常值 (例如 Dim valuesjagged = {{1, 2}, {2, 3, 4}}, ) 會產生編譯程式錯誤 BC30568。 若要更正錯誤,請以括號括住內部陣列常值。 括弧會強制評估陣列常值表達式,結果值會與外部數位常值搭配使用,如下列範例所示。


Module Example
   Public Sub Main()
      Dim values1d = { 1, 2, 3 }
      Dim values2d = {{1, 2}, {2, 3}, {3, 4}}
      Dim valuesjagged = {({1, 2}), ({2, 3, 4})}
   End Sub
End Module

鋸齒狀陣列是一維陣列,其元素包含陣列。 因此,Array.Length 屬性和 Array.GetLength(0) 方法會傳回一維陣列中的元素數目,而 Array.GetLength(1) 會擲出 IndexOutOfRangeException ,因為鋸齒狀陣列不是多維陣列。 您可以藉由擷取每個子陣列的屬性值,來判斷每個子陣列 Array.Length 中的項目數目。 下列範例說明如何判斷不規則陣列中的項目數目。


Module Example
   Public Sub Main()
      Dim jagged = { ({1, 2}), ({2, 3, 4}), ({5, 6}), ({7, 8, 9, 10}) }
      Console.WriteLine($"The value of jagged.Length: {jagged.Length}.")
      Dim total = jagged.Length
      For ctr As Integer = 0 To jagged.GetUpperBound(0)
         Console.WriteLine($"Element {ctr + 1} has {jagged(ctr).Length} elements.") 
         total += jagged(ctr).Length 
      Next
      Console.WriteLine($"The total number of elements in the jagged array: {total}")
   End Sub
End Module
' The example displays the following output:
'     The value of jagged.Length: 4.
'     Element 1 has 2 elements.
'     Element 2 has 3 elements.
'     Element 3 has 2 elements.
'     Element 4 has 4 elements.
'     The total number of elements in the jagged array: 15

長度為零的陣列

Visual Basic 區分未初始化的陣列(其值為 Nothing的陣列)和 長度為零的陣列 或空陣列(沒有元素的陣列)。未初始化的陣列是尚未維度或已指派任何值的陣列。 例如:

Dim arr() As String

宣告一個維度為 -1 的零長度陣列。 例如:

Dim arrZ(-1) As String

在下列情況下,您可能需要建立長度為零的陣列:

  • 為了避免 NullReferenceException 例外狀況,您的程式碼必須存取 Array 類別的成員,例如 LengthRank,或呼叫 Visual Basic 函式,例如 UBound

  • 您想要讓程式代碼保持簡單,以避免需要檢查 Nothing 作為特殊案例。

  • 您的程式代碼會與應用程式程式設計介面 (API) 互動,而應用程式程式設計介面需要您將零長度陣列傳遞至一或多個程式,或從一或多個程式傳回零長度數位列。

分割陣列

在某些情況下,您可能需要將單一數位分割成多個數位。 這牽涉到識別陣列需要分割的點或多個分割點,然後將陣列分成兩個或以上的個別陣列。

備註

本節不會討論根據某些分隔符將單一字串分割成字串陣列。 如需分割字串的資訊,請參閱 String.Split 方法。

分割陣列最常見的準則包括:

  • 陣列中的項目數目。 例如,您可能想要將多個指定的項目數組分割成大約相等的元件數目。 為此,您可以使用Array.Length方法或Array.GetLength方法所傳回的值。

  • 元素的值,作為分隔符,指示陣列應該分割的位置。 您可以呼叫 Array.FindIndexArray.FindLastIndex 方法來搜尋特定值。

決定陣列應該分割的索引或索引之後,您就可以呼叫 Array.Copy 方法來建立個別陣列。

下列範例會將陣列分割成兩個大小大致相等的陣列。 (如果陣列元素的總數是奇數,則第一個陣列的元素數目超過第二個。


Module Example
   Public Sub Main()
      ' Create an array of 100 elements.
      Dim arr(99) As Integer
      ' Populate the array.
      Dim rnd As new Random()
      For ctr = 0 To arr.GetUpperBound(0)
         arr(ctr) = rnd.Next()
      Next
      
      ' Determine how many elements should be in each array.
      Dim divisor = 2
      Dim remainder As Integer
      Dim boundary = Math.DivRem(arr.GetLength(0), divisor, remainder)
            
      ' Copy the array.
      Dim arr1(boundary - 1 + remainder), arr2(boundary - 1) as Integer
      Array.Copy(arr, 0, arr1, 0, boundary + remainder)
      Array.Copy(arr, boundary + remainder, arr2, 0, arr.Length - boundary) 
   End Sub
End Module

下列範例會根據值為「zzz」的元素存在,將字串陣列分割成兩個陣列,該元素作為陣列分隔符。 新的陣列不包含含有分隔符的元素。


Module Example
   Public Sub Main()
      Dim rnd As New Random()
      
      ' Create an array of 100 elements.
      Dim arr(99) As String
      ' Populate each element with an arbitrary ASCII character.
      For ctr = 0 To arr.GetUpperBound(0)
         arr(ctr) = ChrW(Rnd.Next(&h21, &h7F))
      Next
      ' Get a random number that will represent the point to insert the delimiter.
      arr(rnd.Next(0, arr.GetUpperBound(0))) = "zzz"

      ' Find the delimiter.
      Dim location = Array.FindIndex(arr, Function(x) x = "zzz")

      ' Create the arrays.
      Dim arr1(location - 1) As String
      Dim arr2(arr.GetUpperBound(0) - location - 1) As String
      
      ' Populate the two arrays.
      Array.Copy(arr, 0, arr1, 0, location)
      Array.Copy(arr, location + 1, arr2, 0, arr.GetUpperBound(0) - location)
   End Sub
End Module

聯結陣列

您也可以將多個陣列合併成一個較大的陣列。 若要這樣做,您也會使用 Array.Copy 方法。

備註

本節不會討論將字串陣列合併為單一字串。 如需聯結字串數位資訊,請參閱 String.Join 方法。

在將每個陣列的元素複製到新的陣列之前,您必須先確保已經初始化了陣列,並且使其大小足以容納新陣列。 您可以使用下列兩種方式之一來執行此動作:

  • ReDim Preserve使用語句,在將新元素新增至陣列之前,先動態展開陣列。 這是最簡單的技術,但是當您複製大型數位時,可能會導致效能降低和記憶體耗用量過多。
  • 計算新大型數位所需的元素總數,然後將每個來源陣列的元素加入其中。

下列範例會使用第二種方法,將四個包含十個元素的陣列新增至一個單一陣列。

Imports System.Collections.Generic
Imports System.Threading.Tasks

Module Example
   Public Sub Main()
      Dim tasks As New List(Of Task(Of Integer()))
      ' Generate four arrays.
      For ctr = 0 To 3
         Dim value = ctr
         tasks.Add(Task.Run(Function()
                               Dim arr(9) As Integer
                               For ndx = 0 To arr.GetUpperBound(0)
                                  arr(ndx) = value
                               Next
                               Return arr
                            End Function))   
       Next
       Task.WaitAll(tasks.ToArray())
       ' Compute the number of elements in all arrays.
       Dim elements = 0
       For Each task In tasks
          elements += task.Result.Length
       Next
       Dim newArray(elements - 1) As Integer
       Dim index = 0
       For Each task In tasks
          Dim n = task.Result.Length
          Array.Copy(task.Result, 0, newArray, index, n)
          index += n
       Next 
      Console.WriteLine($"The new array has {newArray.Length} elements.")
   End Sub
End Module
' The example displays the following output:
'     The new array has 40 elements.

因為在此情況下,來源陣列全都很小,因此,當我們將每個新陣列的元素新增至陣列時,我們也可以動態展開陣列。 下列範例會執行此動作。

Imports System.Collections.Generic
Imports System.Threading.Tasks

Module Example
   Public Sub Main()
      Dim tasks As New List(Of Task(Of Integer()))
      ' Generate four arrays.
      For ctr = 0 To 3
         Dim value = ctr
         tasks.Add(Task.Run(Function()
                               Dim arr(9) As Integer
                               For ndx = 0 To arr.GetUpperBound(0)
                                  arr(ndx) = value
                               Next
                               Return arr
                            End Function))   
       Next
       Task.WaitAll(tasks.ToArray())

       ' Dimension the target array and copy each element of each source array to it.
       Dim newArray() As Integer = {}
       ' Define the next position to copy to in newArray.
       Dim index = 0
       For Each task In tasks
          Dim n = Task.Result.Length
          ReDim Preserve newArray(newArray.GetUpperBound(0) + n)
          Array.Copy(task.Result, 0, newArray, index, n)
          index += n
       Next 
      Console.WriteLine($"The new array has {newArray.Length} elements.")
   End Sub
End Module
' The example displays the following output:
'     The new array has 40 elements.

集合作為陣列的替代方案

陣列最適合用於創建和使用固定數目的強型別物件。 集合提供更有彈性的方式來處理物件群組。 不同於陣列,您需要使用ReDim語句來明確變更陣列的大小,集合可以根據應用程式的需求動態增長和縮減。

當您使用 ReDim 重新定義陣列時,Visual Basic 會建立新的陣列,並釋放前一個陣列。 執行這項任務需要時間。 因此,如果您處理的項目數目經常變動,或者無法預測需要的最大項目數目,通常使用集合會得到更佳的效能。

對於某些集合,您可以將索引鍵指派給您放入集合中的任何物件,以便使用 索引鍵快速擷取物件。

如果您的集合只包含一個數據類型的專案,您可以使用命名空間中的 System.Collections.Generic 其中一個類別。 泛型集合會強制執行類型安全性,因此無法新增其他數據類型。

如需集合的詳細資訊,請參閱 集合

術語 定義
Visual Basic 中的陣列維度 說明陣列中的排名和維度。
如何:在 Visual Basic 中初始化陣列變數 描述如何使用初始值填入陣列。
如何在 Visual Basic 中排序陣列 示範如何依字母順序排序陣列的元素。
作法:將一個陣列指派給另一個陣列 描述將陣列指派給另一個數位變數的規則和步驟。
陣列疑難排除 討論使用陣列時出現的一些常見問題。

另請參閱