Примечание
Для доступа к этой странице требуется авторизация. Вы можете попробовать войти или изменить каталоги.
Для доступа к этой странице требуется авторизация. Вы можете попробовать изменить каталоги.
Массив представляет собой набор значений, которые называются элементами, которые логически связаны друг с другом. Например, массив может состоять из числа учащихся в каждом классе в грамматической школе; каждый элемент массива — это число учащихся в одном классе. Аналогичным образом, массив может состоять из оценок студентов за курс; каждый элемент массива - это одна оценка.
Для хранения каждого из элементов данных можно использовать отдельные переменные. Например, если приложение анализирует оценки учащихся, мы можем использовать отдельную переменную для каждого учащегося, например englishGrade1
, englishGrade2
и т. д. Этот подход имеет три основных ограничения:
- Мы должны знать во время проектирования точно, сколько уровней нам нужно обрабатывать.
- Обработка большого количества оценок быстро становится неуправляемой. Это, в свою очередь, делает приложение гораздо более вероятным иметь серьезные ошибки.
- Трудно поддерживать. Каждый новый класс, который мы добавляем, требует, чтобы приложение было изменено, перекомпилировано и повторно развернуто.
Используя массив, можно ссылаться на эти связанные значения по одному имени и использовать число, которое называется индексом или подстрокой для идентификации отдельного элемента на основе его позиции в массиве. Индексы массива варьируются от 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
Размер массива
Размер массива — это произведение длин всех его измерений. Он представляет общее количество элементов, содержащихся в данный момент в массиве. Например, в следующем примере объявляется двухмерный массив с четырьмя элементами в каждом измерении. Как показано в выходных данных из примера, размер массива составляет 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
Замечание
Это обсуждение размера массива не относится к рваным массивам. Дополнительные сведения о зубчатых массивах и определении размера зубчатого массива см. в разделе "Зубчатые массивы".
Размер массива можно найти с помощью 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 метод для создания экземпляра массива, тип массива оказывается объектом[].
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
процедуры, укажите тип данных массива и количество измерений в качестве возвращаемого типа инструкции функции. В функции объявите переменную локального массива с одинаковым типом данных и количеством измерений. В инструкции 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 | Показывает, как отсортировать элементы массива в алфавитном порядке. |
Практическое руководство. Назначение одного массива другому массиву | Описывает правила и шаги по присваиванию одного массива другой переменной типа массив. |
Устранение неполадок массивов | Обсуждает некоторые распространенные проблемы, возникающие при работе с массивами. |