陣列是一組稱為「 元素」的值,這些值在邏輯上彼此相關。 例如,陣列可能包含文法學校中每個年級的學生數目;數位的每個元素都是單一年級的學生數目。 同樣地,陣列可能包含學生的班級成績;陣列的每個元素都是單一等級。
您可以使用個別變數來儲存我們的每個資料項。 例如,如果我們的應用程式分析學生成績,我們可以針對每個學生的成績使用不同的變數,例如 englishGrade1
、 englishGrade2
等。此方法有三個主要限制:
- 我們必須在設計階段確切知道需要處理多少個年級。
- 處理大量成績很快就會變得繁瑣。 這反過來又讓應用程式更有可能有嚴重的 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
。 例如,如果提供給陣列常值的值清單包含類型Integer
、Long
和Double
的值,則產生的陣列是類型Double
。 因為 Integer
和 Long
只會擴大為 Double
, Double
是主要類型。 如需詳細資訊,請參閱 擴大和縮小轉換。
備註
您只能針對類型成員中定義為局部變數的陣列使用類型推斷。 如果沒有明確的型別定義,則在類別層級使用陣列常值定義的陣列其型別為 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 類別的成員,例如 Length 或 Rank,或呼叫 Visual Basic 函式,例如 UBound。
您想要讓程式代碼保持簡單,以避免需要檢查
Nothing
作為特殊案例。您的程式代碼會與應用程式程式設計介面 (API) 互動,而應用程式程式設計介面需要您將零長度陣列傳遞至一或多個程式,或從一或多個程式傳回零長度數位列。
分割陣列
在某些情況下,您可能需要將單一數位分割成多個數位。 這牽涉到識別陣列需要分割的點或多個分割點,然後將陣列分成兩個或以上的個別陣列。
備註
本節不會討論根據某些分隔符將單一字串分割成字串陣列。 如需分割字串的資訊,請參閱 String.Split 方法。
分割陣列最常見的準則包括:
陣列中的項目數目。 例如,您可能想要將多個指定的項目數組分割成大約相等的元件數目。 為此,您可以使用Array.Length方法或Array.GetLength方法所傳回的值。
元素的值,作為分隔符,指示陣列應該分割的位置。 您可以呼叫 Array.FindIndex 和 Array.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 中排序陣列 | 示範如何依字母順序排序陣列的元素。 |
作法:將一個陣列指派給另一個陣列 | 描述將陣列指派給另一個數位變數的規則和步驟。 |
陣列疑難排除 | 討論使用陣列時出現的一些常見問題。 |