数组是一组称为元素的值,这些 值在逻辑上彼此相关。 例如,数组可能包含语法学校中每个年级的学生数;数组的每个元素都是单个年级的学生数。 同样,数组可能包含学生对班级的成绩;数组的每个元素都是一个等级。
可以使用各个变量来存储每个数据项。 例如,如果应用程序分析学生成绩,则可以为每个学生的成绩使用单独的变量,例如 englishGrade1
, englishGrade2
等等。此方法有三个主要限制:
- 在设计时必须确切地知道我们必须处理多少个成绩等级。
- 很难快速处理大量的成绩等级。 这反过来又使应用程序更有可能有严重的 bug。
- 很难维护。 我们添加的每个新等级都需要修改、重新编译和重新部署应用程序。
通过使用数组,可以按同名引用这些相关值,并使用一个名为 索引 或 下标 的数字根据其在数组中的位置标识单个元素。 数组的索引范围从 0 开始,到数组中的元素总数减 1。 使用 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}}
使用嵌套数组文本创建和填充数组时,如果嵌套数组文本中的元素数不匹配,则会发生错误。 如果显式声明数组变量具有与数组文本不同的维度数,则也会发生错误。
如同创建一维数组时一样,在使用嵌套数组文本创建多维数组时,可以依赖类型推理。 推理出的类型是用于所有嵌套级别的所有数组文本中的所有值的主控类型。 以下示例使用类型为 Integer
和 Double
的值创建一个类型为 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
数组大小
数组的大小是其所有维度长度的乘积。 它表示数组中当前包含的元素总数。 例如,以下示例声明一个二维数组,其中包含每个维度中的四个元素。 如示例中的输出所示,数组的大小为 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 数组” 部分。
可以使用该 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 位系统上的内存更多。 根据初始化数组时的系统配置,公共语言运行时(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
在以下情况下,可能需要创建零长度数组:
在不引发异常的情况下,代码必须访问 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
语句在向数组添加新元素之前动态展开数组。 这是最简单的技术,但在复制大型数组时,这可能会导致性能下降和内存消耗过多。 - 计算新大型数组所需的元素总数,然后将每个源数组的元素添加到其中。
以下示例使用第二种方法向单个数组添加四个数组,每个数组有 10 个元素。
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 中对数组进行排序 | 演示如何按字母顺序对数组的元素进行排序。 |
如何:将一个数组分配给另一个数组 | 介绍将数组分配给另一个数组变量的规则和步骤。 |
数组疑难解答 | 讨论使用数组时出现的一些常见问题。 |