Matrici in Visual Basic

Una matrice è un set di valori, ovvero elementi definiti logicamente correlati tra loro. Ad esempio, una matrice può essere costituita dal numero di studenti in ogni grado in una scuola di grammatica; ogni elemento della matrice è il numero di studenti in un singolo grado. Analogamente, una matrice può essere costituita dai voti di uno studente per una classe; ogni elemento della matrice è un singolo grado.

È possibile usare singole variabili per archiviare ognuno degli elementi di dati. Ad esempio, se l'applicazione analizza i voti degli studenti, è possibile usare una variabile separata per il grado di ogni studente, ad englishGrade1esempio , englishGrade2e così via. Questo approccio presenta tre limitazioni principali:

  • Dobbiamo sapere in fase di progettazione esattamente il numero di voti che dobbiamo gestire.
  • La gestione di grandi numeri di gradi diventa rapidamente senza problemi. Questo a sua volta rende un'applicazione molto più probabile avere bug gravi.
  • È difficile mantenere. Ogni nuovo grado aggiunto richiede che l'applicazione venga modificata, ricompilata e ridistribuita.

Usando una matrice, è possibile fare riferimento a questi valori correlati con lo stesso nome e usare un numero denominato indice o sottoscript per identificare un singolo elemento in base alla relativa posizione nella matrice. Indici di un intervallo di matrice compreso tra 0 e uno inferiore al numero totale di elementi nella matrice. Quando si usa Visual Basic sintassi per definire le dimensioni di una matrice, specificarne l'indice più alto, non il numero totale di elementi nella matrice. È possibile usare la matrice come unità e la possibilità di eseguire l'iterazione dei relativi elementi consente di conoscere esattamente il numero di elementi che contiene in fase di progettazione.

Di seguito sono riportati alcuni esempi:

' 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)() {}

Elementi di matrice in una matrice semplice

Verrà creata una matrice denominata students per archiviare il numero di studenti in ogni grado in una scuola di grammatica. Gli indici degli elementi sono compresi tra 0 e 6. L'uso di questa matrice è più semplice rispetto alla dichiarazione di sette variabili.

La figura seguente mostra la students matrice. Per ogni elemento della matrice:

  • L'indice dell'elemento rappresenta l'anno scolastico (l'indice 0 rappresenta l'asilo).

  • Il valore contenuto nell'elemento rappresenta il numero degli studenti iscritti a tale anno scolastico.

Diagram showing an array of the numbers of students

L'esempio seguente contiene il codice Visual Basic che crea e usa la matrice:


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

L'esempio esegue tre operazioni:

  • Dichiara una students matrice con sette elementi. Il numero 6 nella dichiarazione della matrice indica l'ultimo indice della matrice. È uno minore del numero di elementi nella matrice.
  • Assegna valori a ogni elemento della matrice. Gli elementi della matrice vengono accessibili usando il nome della matrice e includendo l'indice dell'singolo elemento tra parentesi.
  • Elenca ogni valore della matrice. Nell'esempio viene usata un'istruzione For per accedere a ogni elemento della matrice in base al relativo numero di indice.

La students matrice nell'esempio precedente è una matrice unidimensionale perché usa un indice. Una matrice che usa più indici o sottoscrizioni è denominata multidimensionale. Per altre informazioni, vedere il resto di questo articolo e Dimensioni matrice in Visual Basic.

Creazione di una matrice

È possibile definire le dimensioni di una matrice in diversi modi:

  • È possibile specificare le dimensioni quando la matrice è dichiarata:

    ' 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
    
  • È possibile usare una New clausola per specificare le dimensioni di una matrice quando viene creata:

    ' 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)() {}
    

Se è disponibile una matrice esistente, è possibile ridefinirne la dimensione usando l'istruzione ReDim . È possibile specificare che l'istruzione ReDim mantiene i valori presenti nella matrice oppure è possibile specificare che crea una matrice vuota. L'esempio seguente illustra vari modi di usare l'istruzione ReDim per modificare la dimensione di una matrice esistente.

' 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)

Per altre informazioni, vedere l'istruzione ReDim.

Archiviazione dei valori in una matrice

È possibile accedere a ogni posizione in una matrice usando un indice di tipo Integer. È possibile archiviare e recuperare i valori in una matrice facendo riferimento a ogni posizione della matrice tramite il relativo indice racchiuso tra parentesi. Gli indici per le matrici multidimensionali sono separati da virgole (,). È necessario un indice per ogni dimensione della matrice.

Nell'esempio seguente vengono illustrate alcune istruzioni che archiviano e recuperano i valori nelle matrici.


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

Popolamento di una matrice con valori letterali di matrice

Usando un valore letterale di matrice, è possibile popolare una matrice con un set iniziale di valori contemporaneamente creato. Un valore letterale di matrice è costituito da un elenco di valori delimitati da virgole racchiusi tra parentesi graffe ({}).

Quando si usa un valore letterale di matrice per creare una matrice, è possibile specificare il tipo o usare l'inferenza del tipo per determinare il tipo di matrice. L'esempio seguente mostra entrambe le opzioni.

' 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 }

Quando si usa l'inferenza dei tipi, il tipo della matrice viene determinato dal tipo dominante nell'elenco dei valori letterali . Il tipo dominante è il tipo a cui tutti gli altri tipi della matrice possono essere ampliati. Se non è possibile determinare il tipo univoco, il tipo dominante è il tipo univoco in cui possono restringersi tutti gli altri tipi nella matrice. Se nessuno di questi tipi univoci può essere determinato, il tipo dominante è Object. Se, ad esempio, l'elenco di valori fornito al valore letterale di matrice contiene valori di tipo Integer, Longe Double, la matrice risultante è di tipo Double. Poiché Integer e Long si estende solo a Double, Double è il tipo dominante. Per altre informazioni, vedere Widening and Narrowing Conversions.

Nota

È possibile usare l'inferenza dei tipi solo per le matrici definite come variabili locali in un membro di tipo. Se una definizione di tipo esplicito è assente, le matrici definite con valori letterali di matrice a livello di classe sono di tipo Object[]. Per altre informazioni, vedere Inferenza del tipo locale.

Si noti che l'esempio precedente definisce values come matrice di tipo Double anche se tutti i valori letterali della matrice sono di tipo Integer. È possibile creare questa matrice perché i valori nel valore letterale della matrice possono essere ampliati ai Double valori.

È anche possibile creare e popolare una matrice multidimensionale usando valori letterali matrice annidati. I valori letterali matrice annidati devono avere una serie di dimensioni coerenti con la matrice risultante. Nell'esempio seguente viene creata una matrice bidimensionale di interi usando valori letterali matrice annidati.

' 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}}

Quando si usano valori letterali di matrice annidati per creare e popolare una matrice, si verifica un errore se il numero di elementi nei valori letterali della matrice annidata non corrisponde. Si verifica anche un errore se si dichiara in modo esplicito la variabile di matrice in modo da avere un numero diverso di dimensioni rispetto ai valori letterali della matrice.

Come è possibile per le matrici unidimensionali, è possibile basarsi sull'inferenza dei tipi durante la creazione di una matrice multidimensionale con valori letterali di matrice annidati. Il tipo dedotto è il tipo dominante per tutti i valori in tutti i valori letterali della matrice per tutti i livelli di annidamento. Nell'esempio seguente viene creata una matrice bidimensionale di tipo da valori di tipo Double[,]Integer e Double.

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

Per altri esempi, vedere Procedura: inizializzare una variabile di matrice in Visual Basic.

Iterazione attraverso una matrice

Quando si esegue l'iterazione tramite una matrice, si accede a ogni elemento della matrice dall'indice più basso al più alto o dal più alto al più basso. In genere, usare entrambi i for... Istruzione successiva o per ogni oggetto... Istruzione successiva per scorrere gli elementi di una matrice. Quando non si conoscono i limiti superiori della matrice, è possibile chiamare il Array.GetUpperBound metodo per ottenere il valore più alto dell'indice. Anche se il valore di indice più basso è quasi sempre 0, è possibile chiamare il metodo per ottenere il Array.GetLowerBound valore più basso dell'indice.

Nell'esempio seguente viene eseguita un'iterazione tramite una matrice unidimensionale usando l'istruzione 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

L'esempio seguente illustra come scorrere una matrice multidimensionale usando un'istruzione For...Next . Il metodo GetUpperBound ha un parametro che specifica la dimensione. GetUpperBound(0) restituisce l'indice più alto della prima dimensione e GetUpperBound(1) restituisce l'indice più alto della seconda dimensione.


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

Nell'esempio seguente viene usato un oggetto For Each... Next Statementto iterate attraverso una matrice unidimensionale e una matrice bidimensionale.


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

Dimensioni della matrice

La dimensione di una matrice è il prodotto delle lunghezze di tutte le relative dimensioni e rappresenta il numero totale di elementi attualmente contenuti nella matrice. L'esempio seguente, ad esempio, dichiara una matrice 2dimensionale con quattro elementi in ogni dimensione. Come illustrato dall'esempio, la dimensione della matrice è 16 (o (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

Nota

Questa discussione sulle dimensioni della matrice non si applica alle matrici con estensione frastagliata. Per informazioni sulle matrici frastagliate e sulla determinazione delle dimensioni di una matrice frastagliata, vedere la sezione Matrici frastagliate .

È possibile determinare le dimensioni di una matrice usando la proprietà Array.Length. È possibile trovare la lunghezza di ogni dimensione di una matrice multidimensionale usando il Array.GetLength metodo .

È possibile ridimensionare una variabile di matrice assegnando un nuovo oggetto matrice o usando l'istruzione ReDim Statement . Nell'esempio seguente viene usata l'istruzione ReDim per modificare una matrice di 100 elementi in una matrice di 51 elementi.


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

 

Di seguito sono indicati alcuni elementi importanti relativi alla dimensione di una matrice.

Note
Lunghezza delle dimensioni L'indice di ogni dimensione è basato su 0, ovvero è compreso tra 0 e il limite superiore. Pertanto, la lunghezza di una determinata dimensione è maggiore del limite superiore dichiarato di tale dimensione.
Limiti di lunghezza La lunghezza di ogni dimensione di una matrice è limitata al valore massimo del Integer tipo di dati, ovvero Int32.MaxValue o (2 ^ 31) - 1. La dimensione totale di una matrice, tuttavia, è limitata anche dalla memoria disponibile nel sistema. Se si tenta di inizializzare una matrice che supera la quantità di memoria disponibile, il runtime genera un OutOfMemoryExceptionoggetto .
Dimensione ed elementi della matrice La dimensione di una matrice è indipendente dal tipo di dati dei relativi elementi. Le dimensioni rappresentano sempre il numero totale di elementi, non il numero di byte usati in memoria.
Consumo di memoria Non è possibile fare ipotesi sulla modalità di archiviazione di una matrice in memoria. L'archiviazione dipende dalla larghezza dei dati delle diverse piattaforme. Di conseguenza, è possibile che l'archiviazione di una stessa matrice richieda più memoria in un sistema a 64 bit che in un sistema a 32 bit. A seconda della configurazione di sistema al momento dell'inizializzazione di una matrice, Common Language Runtime (CLR) può assegnare la memoria in modo da compattare al massimo gli elementi oppure in modo da allinearli tutti in base ai limiti dell'hardware. Per le informazioni di controllo di una matrice è richiesto un sovraccarico di archiviazione che aumenta con ogni dimensione aggiunta.

Tipo di matrice

Ogni matrice ha un tipo di dati diverso dal tipo di dati degli elementi. Non esiste un singolo tipo di dati per tutte le matrici. Il tipo di dati di una matrice viene invece determinato dal numero di dimensioni, o rango, della matrice e dal tipo di dati degli elementi nella matrice. Due variabili di matrice sono dello stesso tipo di dati solo quando hanno lo stesso rango e i relativi elementi hanno lo stesso tipo di dati. Le lunghezze delle dimensioni di una matrice non influiscono sul tipo di dati della matrice.

Ogni matrice eredita dalla classe System.Array. È possibile dichiarare una variabile di tipo Array, ma non è possibile creare una matrice di tipo Array. Ad esempio, anche se il codice seguente dichiara che la variabile deve essere di tipo Array e chiama il arr metodo per creare un'istanza della matrice, il Array.CreateInstance tipo della matrice dimostra di essere 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[]

L'istruzione ReDim non può inoltre operare su una variabile dichiarata di tipo Array. Per questi motivi, e per la sicurezza dei tipi, è consigliabile dichiarare ogni matrice come tipo specifico.

È possibile determinare il tipo di dati di una matrice o dei relativi elementi in diversi modi.

  • È possibile chiamare il GetType metodo nella variabile per ottenere un Type oggetto che rappresenta il tipo di runtime della variabile. Nelle proprietà e nei metodi dell'oggetto Type sono presenti informazioni complete.
  • È possibile passare la variabile alla TypeName funzione per ottenere un String con il nome del tipo di runtime.

Nell'esempio seguente viene chiamato sia il GetType metodo che la TypeName funzione per determinare il tipo di una matrice. Il tipo di matrice è Byte(,). Si noti che la Type.BaseType proprietà indica anche che il tipo di base della matrice di byte è la Array classe .


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(,)


Matrici come valori e parametri restituiti

Per restituire una matrice da una routine Function, specificare il tipo di dati della matrice e il numero di dimensioni come tipo restituito dell'istruzione Function. All'interno della funzione dichiarare una variabile di matrice locale con lo stesso tipo di dati degli elementi e lo stesso numero di dimensioni. Includere la variabile di matrice locale senza parentesi nell'istruzione Return.

Per specificare una matrice come parametro in una routine Sub o Function , definire il parametro come matrice con un tipo di dati e un numero di dimensioni specificati. Nella chiamata alla procedura passare una variabile di matrice con lo stesso tipo di dati e il numero di dimensioni.

Nell'esempio seguente la GetNumbers funzione restituisce una Integer()matrice unidimensionale di tipo Integer. La routine ShowNumbers accetta un argomento 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
    

Nell'esempio seguente la GetNumbersMultiDim funzione restituisce una Integer(,)matrice bidimensionale di tipo Integer. La routine ShowNumbersMultiDim accetta un argomento 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

Matrici di matrici

In alcuni casi la struttura dei dati nell'applicazione è bidimensionale, ma non rettangolare. Ad esempio, è possibile usare una matrice per archiviare i dati relativi alla temperatura elevata di ogni giorno del mese. La prima dimensione della matrice rappresenta il mese, ma la seconda dimensione rappresenta il numero di giorni e il numero di giorni in un mese non è uniforme. Una matrice frastagliata, denominata anche matrice di matrici, è progettata per tali scenari. Una matrice frastagliata è una matrice i cui elementi sono anche matrici. Una matrice irregolare e ogni elemento di una matrice irregolare possono avere una o più dimensioni.

Nell'esempio seguente viene usata una matrice di mesi, ogni elemento di cui è una matrice di giorni. Nell'esempio viene usata una matrice frastagliata perché diversi mesi hanno diversi numeri di giorni. Nell'esempio viene illustrato come creare una matrice frastagliata, assegnarne i valori e recuperarne e visualizzarne i valori.

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

L'esempio precedente assegna i valori alla matrice con estensione con estensione in base a un elemento usando un For...Next ciclo. È anche possibile assegnare valori agli elementi di una matrice frastagliata usando valori letterali matrice annidati. Tuttavia, il tentativo di usare valori letterali matrice annidati (ad esempio, Dim valuesjagged = {{1, 2}, {2, 3, 4}}) genera l'errore del compilatore BC30568. Per correggere l'errore, racchiudere i valori letterali della matrice interna tra parentesi. Le parentesi forzano la valutazione dell'espressione letterale della matrice e i valori risultanti vengono usati con il valore letterale della matrice esterna, come illustrato nell'esempio seguente.


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

Una matrice frastagliata è una matrice unidimensionale i cui elementi contengono matrici. Pertanto, la Array.Length proprietà e il Array.GetLength(0) metodo restituiscono il numero di elementi nella matrice unidimensionale e Array.GetLength(1) genera un IndexOutOfRangeException oggetto perché una matrice frastagliata non è multidimensionale. Si determina il numero di elementi in ogni sottoarray recuperando il valore di ogni proprietà della Array.Length sottoarray. Nell'esempio seguente viene illustrato come determinare il numero di elementi in una matrice frastagliata.


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

Matrici a lunghezza zero

Visual Basic differenzia tra una matrice non inizializzata (una matrice il cui valore è Nothing) e una matrice a lunghezza zero o una matrice vuota (una matrice senza elementi). Una matrice non inizializzata è una che non è stata ridimensionata o che ha alcun valore assegnato a esso. Ad esempio:

Dim arr() As String

Una matrice a lunghezza zero viene dichiarata con una dimensione di -1. Ad esempio:

Dim arrZ(-1) As String

Potrebbe essere necessario creare una matrice di lunghezza zero nelle circostanze seguenti:

  • Senza rischiare un'eccezioneNullReferenceException, il codice deve accedere ai membri della Array classe, ad esempio o Rank, o chiamare una funzione Visual Basic, ad esempio UBoundLength .

  • Si vuole mantenere il codice semplice senza dover controllare Nothing come caso speciale.

  • Il codice interagisce con un'API (Application Programming Interface) che richiede il passaggio di una matrice di lunghezza zero a una o più routine oppure che restituisce una matrice di lunghezza zero da una o più routine.

Divisione di una matrice

In alcuni casi, potrebbe essere necessario suddividere una singola matrice in più matrici. Ciò comporta l'identificazione del punto o dei punti in cui la matrice deve essere suddivisa e quindi spittinge la matrice in due o più matrici separate.

Nota

Questa sezione non illustra la suddivisione di una singola stringa in una matrice di stringhe in base a alcuni delimitatori. Per informazioni sulla suddivisione di una stringa, vedere il String.Split metodo .

I criteri più comuni per la suddivisione di una matrice sono:

  • Numero di elementi nella matrice. Ad esempio, è possibile dividere una matrice di più di un numero specificato di elementi in un numero di parti approssimativamente uguali. A questo scopo, è possibile usare il valore restituito dal Array.Length metodo o Array.GetLength .

  • Valore di un elemento, che funge da delimitatore che indica dove deve essere divisa la matrice. È possibile cercare un valore specifico chiamando i Array.FindIndex metodi e Array.FindLastIndex .

Dopo aver determinato l'indice o gli indici in corrispondenza del quale la matrice deve essere suddivisa, è quindi possibile creare le singole matrici chiamando il Array.Copy metodo .

Nell'esempio seguente viene divisa una matrice in due matrici di dimensioni approssimativamente uguali. Se il numero totale di elementi della matrice è dispari, la prima matrice ha un altro elemento rispetto al secondo.


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

Nell'esempio seguente viene suddivisa una matrice di stringhe in due matrici in base alla presenza di un elemento il cui valore è "zzz", che funge da delimitatore della matrice. Le nuove matrici non includono l'elemento contenente il delimitatore.


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

Unione di matrici

È anche possibile combinare un numero di matrici in una singola matrice più grande. A tale scopo, si usa anche il Array.Copy metodo .

Nota

Questa sezione non illustra l'aggiunta di una matrice di stringhe in una singola stringa. Per informazioni sull'aggiunta di una matrice di stringhe, vedere il String.Join metodo .

Prima di copiare gli elementi di ogni matrice nella nuova matrice, è prima necessario assicurarsi di aver inizializzato la matrice in modo che sia abbastanza grande per supportare la nuova matrice. Questa operazione può essere eseguita in due modi:

  • Usare l'istruzione per espandere dinamicamente la ReDim Preserve matrice prima di aggiungere nuovi elementi. Questa è la tecnica più semplice, ma può causare una riduzione delle prestazioni e un consumo eccessivo di memoria quando si copiano matrici di grandi dimensioni.
  • Calcolare il numero totale di elementi necessari per la nuova matrice di grandi dimensioni, quindi aggiungere gli elementi di ogni matrice di origine.

Nell'esempio seguente viene usato il secondo approccio per aggiungere quattro matrici con dieci elementi ciascuno a una singola matrice.

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.

Poiché in questo caso le matrici di origine sono tutte di piccole dimensioni, è anche possibile espandere dinamicamente la matrice man mano che si aggiungono gli elementi di ogni nuova matrice. Nell'esempio seguente viene eseguita questa operazione.

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.

Raccolte come alternativa alle matrici

Le matrici sono estremamente utili per la creazione e l'uso di un numero fisso di oggetti fortemente tipizzati. Le raccolte consentono di lavorare in modo più flessibile con gruppi di oggetti. A differenza delle matrici, che richiedono di modificare in modo esplicito le dimensioni di una matrice con l'istruzioneReDim, le raccolte aumentano e si riducono in modo dinamico in base alle esigenze di un'applicazione.

Quando si usa ReDim per ridimensionare una matrice, Visual Basic crea una nuova matrice e rilascia quella precedente. Questa operazione causa un aumento del tempo di esecuzione. Pertanto, se il numero di elementi usati di frequente o non è possibile stimare il numero massimo di elementi necessari, in genere si otterranno prestazioni migliori usando una raccolta.

Per alcune raccolte è possibile assegnare una chiave a qualsiasi oggetto inserito nella raccolta in modo da recuperare rapidamente l'oggetto usando la chiave.

Se la raccolta contiene elementi di un solo tipo di dati, è possibile usare una delle classi dello spazio dei nomi System.Collections.Generic. In una raccolta generica viene imposta l'indipendenza dai tipi, in modo da impedire che vengano aggiunti altri tipi di dati alla raccolta.

Per altre informazioni sulle raccolte, vedere Raccolte.

Termine Definizione
Array Dimensions in Visual Basic Illustra il numero di dimensioni, o rango, e le dimensioni delle matrici.
Procedura: Inizializzare una variabile di matrice in Visual Basic Descrive come popolare le matrici con valori iniziali.
Procedura: ordinare una matrice in Visual Basic Illustra come ordinare alfabeticamente gli elementi di una matrice.
Procedura: Assegnare una matrice a un'altra matrice Descrive regole e passaggi per l'assegnazione di una matrice a un'altra variabile di matrice.
Risoluzione dei problemi relativi alle matrici Illustra alcuni problemi comuni che si verificano quando si usano le matrici.

Vedi anche