Matrizes no Visual Basic

Uma matriz é um conjunto de valores, que são chamados de elementos, que estão logicamente relacionados entre si. Por exemplo, uma matriz pode consistir no número de alunos em cada série em uma escola de gramática; cada elemento da matriz é o número de alunos em uma única série. Da mesma forma, uma matriz pode consistir em notas de um aluno para uma classe; cada elemento da matriz é uma única nota.

É possível usar variáveis individuais para armazenar cada um de nossos itens de dados. Por exemplo, se nosso aplicativo analisar as notas dos alunos, podemos usar uma variável separada para a nota de cada aluno, como englishGrade1, englishGrade2etc. Essa abordagem tem três limitações principais:

  • Temos que saber exatamente em tempo de design quantas notas temos que lidar.
  • Lidar com grandes números de notas rapidamente torna-se desordado. Isso, por sua vez, torna um aplicativo muito mais propenso a ter bugs graves.
  • É difícil de manter. Cada nova nota que adicionamos requer que o aplicativo seja modificado, recompilado e reimplantado.

Usando uma matriz, você pode consultar esses valores relacionados com o mesmo nome e usar um número que é chamado de índice ou subscrito para identificar um elemento individual baseado na sua posição na matriz. Os índices de uma matriz variam de 0 a 1 a menos do que o número total de elementos na matriz. Quando você usa a sintaxe do Visual Basic para definir o tamanho de uma matriz, especifique seu índice mais alto, não o número total de elementos na matriz. Você pode trabalhar com a matriz como uma unidade e a capacidade de iterar seus elementos libera você de precisar saber exatamente quantos elementos ele contém em tempo de design.

Alguns exemplos rápidos antes da explicação:

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

Elementos da matriz em uma matriz simples

Vamos criar uma matriz nomeada students para armazenar o número de alunos em cada série em uma escola de gramática. Os índices dos elementos variam de 0 a 6. Ter essa matriz é mais simples do que declarar sete variáveis.

A ilustração a seguir mostra a matriz students. Para cada elemento da matriz:

  • O índice do elemento representa a classificação (o índice 0 representa o jardim de infância).

  • O valor contido no elemento representa o número de alunos nessa série.

Diagrama mostrando uma matriz dos números de alunos

O exemplo a seguir contém o código do Visual Basic que cria e usa a matriz:


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

O exemplo faz três coisas:

  • Ele declara uma students matriz com sete elementos. O número 6 na declaração de matriz indica o último índice na matriz; ele é um menor que o número de elementos na matriz.
  • Ele atribui valores a cada elemento na matriz. Os elementos de matriz são acessados usando o nome da matriz e incluindo o índice do elemento individual em parênteses.
  • Ele lista cada valor da matriz. O exemplo usa uma For instrução para acessar cada elemento da matriz por seu número de índice.

A students matriz no exemplo anterior é uma matriz unidimensional porque usa um índice. Uma matriz que usa mais de um índice ou subscrito é chamada multidimensional. Para obter mais informações, consulte o restante deste tópico e Dimensões de matriz no Visual Basic.

Criando uma matriz

Você pode definir o tamanho de uma matriz de várias maneiras:

  • Você pode especificar o tamanho quando uma matriz é declarada:

    ' 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
    
  • Você pode usar uma cláusula New para fornecer o tamanho de uma matriz quando ela é criada:

    ' 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 tiver uma matriz existente, você poderá redefinir o tamanho usando a instrução ReDim. Você pode especificar que a instrução ReDim deve manter os valores na matriz ou você pode especificar que ela crie uma matriz vazia. O exemplo a seguir mostra os diferentes usos da instrução ReDim para modificar o tamanho de uma matriz existente.

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

Para obter mais informações, consulte Instrução ReDim.

Armazenando valores em uma matriz

Você pode acessar cada local em uma matriz usando um índice do tipo Integer. Você pode armazenar e recuperar valores em uma matriz, fazendo referência a cada local de matriz usando seu índice entre parênteses. Índices de matrizes multidimensionais são separados por vírgulas (,). Você precisa de um índice para cada dimensão de matriz.

O exemplo a seguir mostra algumas instruções que armazenam valores em matrizes.


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

Populando uma matriz com literais de matriz

Usando um literal de matriz, você pode preencher uma matriz com um conjunto inicial de valores ao mesmo tempo em que a cria. Um literal de matriz consiste em uma lista de valores separados por vírgulas que são colocados entre chaves ({}).

Ao criar uma matriz usando um literal de matriz, você pode fornecer o tipo de matriz ou usar inferência de tipos para determinar o tipo de matriz. O exemplo abaixo mostra duas opções.

' 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 você usa a inferência de tipos, o tipo da matriz é determinado pelo tipo dominante na lista de valores que é fornecida para o literal de matriz. O tipo dominante é um tipo exclusivo ao qual todos os outros tipos no literal da matriz podem ser ampliados. Se esse tipo exclusivo não puder ser determinado, o tipo dominante será o tipo exclusivo ao qual todos os outros tipos na matriz poderão restringir. Se nenhum desses tipos exclusivos puder ser determinado, o tipo dominante será Object. Por exemplo, se a lista de valores que é fornecida para o literal de matriz contiver os valores do tipo Integer, Long e Double, a matriz resultante será do tipo Double. Porque Integer e Long ampliar somente para Double, Double é o tipo dominante. Para obter mais informações, consulte Ampliando e restringindo conversões.

Observação

Você pode usar a inferência de tipo apenas para matrizes definidas como variáveis locais em um membro do tipo. Se uma definição de tipo explícito estiver ausente, as matrizes definidas com literais de matriz no nível da classe serão do tipo Object[]. Para obter mais informações, confira Inferência de tipo de variável local.

Observe que o exemplo anterior define values como uma matriz de tipo Double, embora todos os literais de matriz sejam do tipo Integer. Você pode criar essa matriz porque os valores no literal da matriz podem ser ampliados para Double valores.

Você pode criar uma matriz multidimensional usando literais de matriz aninhados. Os literais de matriz aninhados devem ter uma dimensão e o número de dimensões, ou classificação, consistentes com a matriz resultante. O exemplo de código a seguir cria uma matriz bidimensional de números inteiros usando um literal de matriz.

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

Ao usar literais de matriz aninhados para criar e preencher uma matriz, ocorrerá um erro se o número de elementos nos literais de matriz aninhados não corresponder. Um erro também ocorrerá se você declarar explicitamente a variável de matriz para ter um número diferente de dimensões que os literais da matriz.

Assim como você pode para matrizes unidimensionais, você pode confiar na inferência de tipo ao criar uma matriz multidimensional com literais de matriz aninhada. Quando você usa a inferência de tipos, o tipo inferido é o tipo dominante para todos os valores em todos os literais de matriz para um nível de aninhamento. O exemplo de código a seguir cria uma matriz bidimensional de tipo Double[,] de valores que são do tipo Integer e Double.

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

Para obter exemplos adicionais, consulte Como inicializar uma variável de matriz no Visual Basic.

Iterando por uma matriz

Quando você itera por uma matriz, pode acessar cada elemento na matriz do índice menor para o índice maior. Normalmente, use o For... Instrução Next ou For Each... Próxima Instrução para iterar por meio dos elementos de uma matriz. Quando você não conhece os limites superiores da matriz, pode chamar o Array.GetUpperBound método para obter o valor mais alto do índice. Embora o menor valor de índice seja quase sempre 0, você pode chamar o Array.GetLowerBound método para obter o valor mais baixo do índice.

O exemplo a seguir itera por meio de uma matriz unidimensional usando a instrução 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

O exemplo a seguir itera por meio de uma matriz multidimensional usando uma instrução For...Next. O método GetUpperBound tem um parâmetro que especifica a dimensão. GetUpperBound(0) retorna o índice mais alto para a primeira dimensão, e GetUpperBound(1) retorna o índice mais alto para a segunda dimensão.


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

O exemplo a seguir usa um For Each... Próxima Instruçãopara iterar por meio de uma matriz unidimensional e uma matriz bidimensional.


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

Tamanho da matriz

O tamanho de uma matriz é o produto dos comprimentos de todas as suas dimensões. Ele representa o número total de elementos contidos no momento na matriz. Por exemplo, o exemplo a seguir declara uma matriz bidimensional com quatro elementos em cada dimensão. Como mostra a saída do exemplo, o tamanho da matriz é 16 (ou (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

Observação

Essa discussão sobre o tamanho da matriz não se aplica a matrizes irregulares. Para obter informações sobre matrizes irregulares e determinar o tamanho de uma matriz irregular, consulte a seção matrizes denteadas.

Você pode encontrar o tamanho de uma matriz usando a propriedade Array.Length. Você pode encontrar o tamanho de cada dimensão de uma matriz multidimensional usando o método Array.GetLength.

Você pode redimensionar uma variável de matriz atribuindo um novo objeto de matriz a ela ou usando a ReDiminstrução. O exemplo a seguir usa a ReDim instrução para alterar uma matriz de 100 elementos para uma matriz de 51 elementos.


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

 

Há várias coisas para ter em mente ao lidar com o tamanho de uma matriz.

Observações
Tamanho da dimensão O índice de cada dimensão é baseado em 0, o que significa que ele varia de 0 até o limite superior. Portanto, o tamanho de uma determinada dimensão é maior em 1 dígito que o limite superior declarado para a dimensão.
Limites de comprimento O tamanho de cada dimensão de uma matriz é limitado ao valor máximo do tipo de dados Integer, que é Int32.MaxValue ou (2 ^ 31) – 1. No entanto, o tamanho total de uma matriz também é limitado pela memória disponível no sistema. Se você tentar inicializar uma matriz que excede a quantidade de RAM disponível, o Common Language Runtime lançará uma exceção OutOfMemoryException.
Tamanho e tamanho do elemento Um tamanho de matriz é independente do tipo de dados de seus elementos. O tamanho sempre representa o número total de elementos, não o número de bytes que eles consomem no armazenamento.
Consumo de memória Não é seguro fazer suposições sobre como uma matriz é armazenada na memória. O armazenamento varia em plataformas de larguras de dados diferentes, então a mesma matriz pode consumir mais memória em um sistema de 64 bits que em um sistema de 32 bits. Dependendo da configuração do sistema ao inicializar uma matriz, o CLR (Common Language Runtime) pode atribuir armazenamento para elementos do pacote o mais próximo possível, ou alinhá-los em limites naturais de hardware. Além disso, uma matriz de armazenamento requer sobrecarga de armazenamento para suas informações de controle, e essa sobrecarga aumenta com cada nova dimensão.

O tipo de matriz

Cada matriz tem um tipo de dados, que difere do tipo de dados de seus elementos. Não há nenhum tipo de dados único para todas as matrizes. Em vez disso, o tipo de dados de uma matriz é determinado pelo número de dimensões, ou classificação, da matriz e o tipo de dados dos elementos na matriz. Duas variáveis de matriz são consideradas tendo os mesmos dados somente quando elas têm a mesma classificação e quando seus elementos têm os mesmo tipo de dados. Os comprimentos das dimensões de uma matriz não influenciam o tipo de dados de matriz.

Cada matriz herda da classe System.Array e você pode declarar uma variável para ser do tipo Array, mas não pode criar uma matriz do tipo Array. Por exemplo, embora o código a seguir declare que a arr variável é do tipo Array e chama o Array.CreateInstance método para instanciar a matriz, o tipo da matriz se mostra Objeto[].


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[]

Além disso, a instrução ReDim não pode operar em uma variável declarada como tipo Array. Por esses motivos, e para a segurança de tipo, é aconselhável declarar cada matriz como um tipo específico.

Você pode descobrir o tipo de dados de uma matriz ou seus elementos de várias maneiras.

  • Você pode chamar o método GetType na variável para receber um objeto Type para o tipo de tempo de execução da variável. O objeto Type mantém informações abrangentes em suas propriedades e métodos.
  • Você pode passar a variável para o a função TypeName para receber um String que contém o nome do tipo de tempo de execução.

O exemplo a seguir chama o GetType método e a TypeName função para determinar o tipo de uma matriz. O tipo de matriz é Byte(,). Observe que a Type.BaseType propriedade também indica que o tipo base da matriz de bytes é a 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(,)


Matrizes como valores de retorno e parâmetros

Para retornar uma matriz de um procedimento Function, especifique o tipo de dados de matriz e o número de dimensões como o tipo de retorno de instrução de função. Dentro da função, declare uma variável da matriz local com o mesmo tipo de dados e número de dimensões. Na instrução Return, inclua a variável da matriz local sem parênteses.

Para especificar uma matriz como um parâmetro para um procedimento Sub ou Function, defina o parâmetro como uma matriz com um tipo de dados especificado e o número de dimensões. Na chamada para o procedimento, envie uma variável de matriz com o mesmo tipo de dados e o número de dimensões.

No exemplo a seguir, a GetNumbers função retorna uma Integer()matriz unidimensional do tipo Integer. O procedimento ShowNumbers aceita um argumento 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
    

No exemplo a seguir, a GetNumbersMultiDim função retorna uma Integer(,)matriz bidimensional do tipo Integer. O procedimento ShowNumbersMultiDim aceita um argumento 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

Matrizes denteadas

Às vezes, a estrutura de dados em seu aplicativo é bidimensional, mas não retangular. Por exemplo, você pode usar uma matriz para armazenar dados sobre a alta temperatura de cada dia do mês. A primeira dimensão da matriz representa o mês, mas a segunda dimensão representa o número de dias e o número de dias em um mês não é uniforme. Uma matriz irregular, que também é chamada de matrizes, foi projetada para esses cenários. Uma matriz denteada é uma matriz cujos elementos são matrizes. Uma matriz denteada e cada elemento em uma matriz denteada podem ter uma ou mais dimensões.

O exemplo a seguir tem uma matriz de meses, cada elemento é uma matriz de dias. O exemplo usa uma matriz irregular porque meses diferentes têm números diferentes de dias. O exemplo mostra como criar uma matriz irregular, atribuir valores a ela e recuperar e exibir seus valores.

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

O exemplo anterior atribui valores à matriz irregular em uma base elemento por elemento usando um For...Next loop. Você também pode atribuir valores aos elementos de uma matriz irregular usando literais de matriz aninhada. No entanto, a tentativa de usar literais de matriz aninhada (por exemplo, Dim valuesjagged = {{1, 2}, {2, 3, 4}}) gera o erro do compilador BC30568. Para corrigir o erro, coloque entre parênteses os literais da matriz interna. Os parênteses forçam a avaliação da expressão literal de matriz, e os valores resultantes são usados com o literal de matriz externo, como mostra o código a seguir.


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

Uma matriz denteada é uma matriz unidimensional cujos elementos contém matrizes. Portanto, a Array.Length propriedade e o Array.GetLength(0) método retornam o número de elementos na matriz unidimensional e Array.GetLength(1) gera um IndexOutOfRangeException porque uma matriz irregular não é multidimensional. Você determina o número de elementos em cada subarray recuperando o valor da propriedade de Array.Length cada subarray. O exemplo a seguir ilustra como determinar o número de elementos em uma matriz irregular.


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

Matrizes de tamanho igual a zero

O Visual Basic diferencia entre uma matriz não inicializada (uma matriz cujo valor é Nothing) e uma matriz de comprimento zero ou uma matriz vazia (uma matriz que não tem elementos). Uma matriz não inicializada é aquela que não foi dimensionada ou teve valores atribuídos a ela. Por exemplo:

Dim arr() As String

Uma matriz de comprimento zero é declarada com uma dimensão de -1. Por exemplo:

Dim arrZ(-1) As String

Talvez seja necessário criar uma matriz de tamanho igual a zero nas seguintes circunstâncias:

  • Sem arriscar uma exceção NullReferenceException, seu código precisa acessar membros da classe Array, como Length ou Rank, ou chamar uma função do Visual Basic como UBound.

  • Você deseja manter o código de consumo mais simples por não ter que procurar Nothing como um caso especial.

  • Seu código interage com uma API (interface de programação do aplicativo) que exige que você passe uma matriz de tamanho igual a zero para um ou mais procedimentos ou retorna uma matriz de tamanho igual a zero de um ou mais procedimentos.

Dividir uma matriz

Em alguns casos, talvez seja necessário dividir uma única matriz em várias matrizes. Isso envolve identificar o ponto ou os pontos em que a matriz deve ser dividida e, em seguida, cuspir a matriz em duas ou mais matrizes separadas.

Observação

Esta seção não discute a divisão de uma única cadeia de caracteres em uma matriz de cadeias de caracteres com base em algum delimitador. Para obter informações sobre como dividir uma cadeia de caracteres, consulte o String.Split método.

Os critérios mais comuns para dividir uma matriz são:

  • O número de elementos na matriz. Por exemplo, talvez você queira dividir uma matriz de mais do que um número especificado de elementos em um número de partes aproximadamente iguais. Para essa finalidade, você pode usar o valor retornado pelo método ou Array.Length pelo Array.GetLength método.

  • O valor de um elemento, que serve como um delimitador que indica onde a matriz deve ser dividida. Você pode pesquisar um valor específico chamando os métodos e Array.FindIndex os Array.FindLastIndex métodos.

Depois de determinar o índice ou os índices nos quais a matriz deve ser dividida, você poderá criar as matrizes individuais chamando o Array.Copy método.

O exemplo a seguir divide uma matriz em duas matrizes de tamanho aproximadamente igual. (Se o número total de elementos de matriz for ímpar, a primeira matriz terá um elemento a mais que o segundo.)


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

O exemplo a seguir divide uma matriz de cadeias de caracteres em duas matrizes com base na presença de um elemento cujo valor é "zzz", que serve como delimitador de matriz. As novas matrizes não incluem o elemento que contém o delimitador.


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

Como unir matrizes

Você também pode combinar várias matrizes em uma única matriz maior. Para fazer isso, você também usa o método Array.Copy.

Observação

Esta seção não discute a junção de uma matriz de cadeias de caracteres em uma única cadeia de caracteres. Para obter informações sobre como ingressar em uma matriz de cadeias de caracteres, consulte o String.Join método.

Antes de copiar os elementos de cada matriz para a nova matriz, primeiro você deve garantir que você tenha inicializado a matriz para que ela seja grande o suficiente para acomodar a nova matriz. É possível fazer isso de duas formas:

  • Use a ReDim Preserve instrução para expandir dinamicamente a matriz antes de adicionar novos elementos a ela. Essa é a técnica mais fácil, mas pode resultar em degradação de desempenho e consumo excessivo de memória quando você está copiando grandes matrizes.
  • Calcule o número total de elementos necessários para a nova matriz grande e adicione os elementos de cada matriz de origem a ela.

O exemplo a seguir usa a segunda abordagem para adicionar quatro matrizes com dez elementos cada uma a uma única matriz.

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.

Como nesse caso as matrizes de origem são todas pequenas, também podemos expandir dinamicamente a matriz à medida que adicionamos os elementos de cada nova matriz a ela. O exemplo a seguir faz isso.

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.

Coleções como uma alternativa para matrizes

As matrizes são mais úteis para criar e trabalhar com um número fixo de objetos fortemente tipados. As coleções fornecem uma maneira mais flexível de trabalhar com grupos de objetos. Ao contrário das matrizes, que exigem que você altere explicitamente o tamanho de uma matriz com a ReDimInstrução, as coleções crescem e reduzem dinamicamente à medida que as necessidades de um aplicativo mudam.

Quando você usa ReDim para redimensionar uma matriz, o Visual Basic cria uma nova matriz e libera a anterior. Isso leva o tempo da execução. Portanto, se o número de itens com o qual você está trabalhando for alterado com frequência ou se você não puder prever o número máximo de itens que precisa, você poderá obter melhor desempenho usando uma coleção.

Para algumas coleções, você pode atribuir uma chave para qualquer objeto que coloque na coleção para que você possa recuperar rapidamente o objeto usando a chave.

Se a coleção contiver elementos de apenas um tipo de dados, você poderá usar uma das classes no namespace System.Collections.Generic. Uma coleção genérica impõe segurança de tipos para que nenhum outro tipo de dados possa ser adicionado a ela.

Para obter mais informações sobre coleções, consulte Coleções.

Termo Definição
Dimensões de matriz no Visual Basic Explica a classificação e as dimensões em matrizes.
Como inicializar uma variável de matriz no Visual Basic Descreve como preencher matrizes com valores iniciais.
Como classificar uma matriz no Visual Basic Mostra como classificar os elementos de uma matriz em ordem alfabética.
Como atribuir uma matriz a outra matriz Descreve as regras e as etapas para atribuir uma matriz a outra variável de matriz.
Solução de problemas de matrizes Aborda alguns problemas comuns que surgem ao trabalhar com matrizes.

Confira também