Редименсиране на масив
Инструкция ReDim се използва за смяна на размера на масива. Това се нарича редименсиране - понятието не предизвиква съмнение
при някой, който не знае разликата между дименсия
и размер на масива! Във всеки случай, редименсирането сменя размера на
масива, не неговата дименсия.
Фактически,
ние вече казахме, че дименсията на масива не може да бъде сменяна. Функция UBound връща горния лимит на
координатите на масива. Синтаксисът е следният:
UBound(MyArray, CoordinateIndex)
където CoordinateIndex е индекс на координатата за която искаме горния край. Eто пример за редименсиране на
масив:
Dim MyArray(10, 10) As Integer
Msgbox(UBound(MyArray, 2)) ' Displays 10
ReDim MyArray(15, 20)
Msgbox(UBound(MyArray, 2)) ' Displays 20
Когато
масива се редименсира чрез ReDim без квалификация, всички данни в
масива се губят; така че масивът се реинициализара. Затова чрез ключова
дума Preserve, когато се използва заедно с ReDim, се редименсира
масива, като се запазват
всички текущи стойности. Когато се използва ключова дума Preserve, само
последните координати на масива могат да се
сменят. Обръщайки се
към масив дефиниран по-рано, кодът генерира грешка:
ReDim Preserve MyArray(50, 20)
Вероятно
няма да се изненадате да научите, че редименсирането на масив е интензивен във
времето процес (time-intensive). Когато
редименсираме, заставаме с лице към весдесъщата дихотомия между запазване на
място и съхраняване на време. Нека да имаме кодов сегмент
използван за популяризиране на масиви:
Dim MyArray(100) As Integer
Dim i As Integer, iNext As Integer
iNext = 0
Do While (Some condition)
If (some condition here) Then
' добавяне на елемент към масива
If ubound(MyArray) < iNext Then
ReDim Preserve MyArray(iNext + 100)
End If
MyArray(iNext) = (whatever)
iNext = iNext + 1
End If
Loop
Ключът
на този подход се състои от решението колко да увеличаваме масива, всеки път
когато това е необходимо. Ако искаме да спестим място, би следвало да
увеличаваме размера на масива всеки път с 1:
ReDim Preserve MyArray(iNext + 1)
Но
това би било много неефективно. Алтернативно бихме увеличили на 1,000:
ReDim Preserve MyArray(iNext + 1000)
Но
това се нуждае от много допълнително място. Понякога е нужно екпериментиране, за да се реши и вземе
необходимия компромис за спестяване на място и време.
Класът Array Class
Класът
Array няма публичен конструктор,
защото процедурата му New има
защитена област на действие (Protected
scope). Но вие може както вече показахме да използвате инициализация:
` Инициализация на масив с числа на степен 2
Dim intArr() As Integer = {1, 2, 4, 8, 16, 32, 64, 128,
256, 512}
` Не инициализиран дву-дименсионелен масив
Dim lngArr(10, 20) As Long
` Празен масив
Dim dblArr() As Double
Вариация за
инициализиране на ход:
` Създаване на временен масив.
Dim tmp() As Integer = {2, 5, 9, 13}
` Свойството obj.ValueArray създава масив от
цели числа-Integer.
obj.ValueArray = tmp
` Нулира временните променливи.
tmp = Nothing
Може и на един
ред:
obj.ValueArray = New Long() {2, 5, 9, 13}
Ако се
обърнем за достъп до празен масив ще получим грешка. Защото масивът е обект,
можем да го тестваме чрез оператор Is
и след това ReDim
е задължително:
If dblArr Is Nothing Then
ReDim dblArr(100)
End If
Можем да
направим сечение на масива за неговия ранг, използвайки свойството му Rank, а
за броя на елементите на масива - свойството му Length:
` продължаваме примера
Console.WriteLine(lngArr.Rank) ' => 2
` lngArr има 11*21 елементи.
Console.WriteLine(lngArr.Length) ' => 231
Методът GetLength
връща броя на елементите при дадена дименсия, а вече изяснихме, че GetLowerBound
и GetUpperBound
връщат най-ниския и най-високия индекс:
`продължаваме
примера
Console.WriteLine(lngArr.GetLength(0)) ' => 11
Console.WriteLine(lngArr.GetLowerBound(1)) ' => 0
Console.WriteLine(lngArr.GetUpperBound(1)) ' => 20
Можем да
посетим всички елементи на много-дименсионален масив чрез цикъла For Each и стриктно дефинирани
променливи:
Dim strArr(,) As String = {{"00", "01",
"02"}, {"10", "11", "12"}}
Dim s As String
For Each s In strArr
Console.Write(s & ",") ' дава 00,01,02,10,11,12
Next
Visual Basic .NET следва естествената
поредова последователност (row-wise
order).