Site:  Cours VB.net  
1.6.4 Les tableaux

C'est un beau tableau, mais en VB, c'est pas ça un tableau!!

Les tableaux permettent de regrouper des données de même type.

Les tableaux vous permettent de faire référence à un ensemble de variables par le même nom et d'utiliser un numéro, appelé index ou indice, pour les distinguer.

Comment déclarer un tableau :

Dim Tableau(3) As Integer    'déclare un tableau de 4 entiers

On remarque que, dés la déclaration du tableau, le nombre d'éléments est bien défini et restera toujours le même.

Dim Tableau(3) As Integer entraîne la création des variables 'Integer' suivante:

Tableau (0)

Tableau (1)

Tableau (2)

Tableau (3) 

Contenu du tableau:

0

0

0

0

 

     soit 4 éléments

Noter que comme c'est un tableau d'entier, juste après la création du tableau les éléments sont initialisés à 0.

Le tableau commence toujours par l’indice 0

Le nombre d'éléments dans le tableau est toujours égale à l'indice de dimension + 1 (ou l'indice du dernier élément+1)

Dim Tableau(3) comporte 4 éléments (éléments d'index 0 à 3).

 

Tableau(1)= 12 permet d’affecter le nombre 12 au 2eme élément du tableau.

0

12

0

0

 

S=Tableau(1) permet d’affecter à la variable S le 2eme élément du tableau.

 

Un tableau peut avoir plusieurs dimensions :

Dim T(2,2)      3 X 3 éléments

Pour un tableau à 2 dimensions le premier argument représente les lignes, le second les colonnes.

Voyons pour chaque élément du tableau le numéro de ligne et celui de la colonne: (pas le contenu des éléments ici mais leur index)

élément:0,0 élément:0,1 élément:0,2
élément:1,0 élément:1,1 élément:1,2
élément:2,0 élément:2,1 élément:2,2

 

Exemple:

La première ligne comporte les 3 éléments: T(0,0) T(0,1) et T(0,2)

Pour mettre 33 dans l'élément central:

Dim T(2,2) As Integer

T(1,1)=33

voyons le contenu du tableau:

0 0 0
0 33 0
0 0 0

 

Il est possible de créer des tableaux à 3, 4 ..dimensions.

Exemple:

Dim T(3,1,2)   crée un tableau de 4X2X3 éléments.

 

 

On peut créer des tableaux de tableaux:

Dim T(2),(2)    Il a autant d'élément que le tableau T (2,2) (mais pour l'accès à un élément, ils fonctionnent plus vite)

 

Il est possible de créer des tableaux avec tous les types de variable (y compris les structures) 

Dim Mois(11) As String    'tableau de String de 12 éléments

Notez que dans ce cas les éléments contiennent Nothing car le tableau contient des String et quand on déclare une String, elle contient Nothing au départ.

 

On peut initialiser un tableau (Donner une valeur aux éléments):

En effet après dimensionnement d'un tableau, il contient:

la valeur 0 si c'est un tableau de numérique.

Nothing si c'est un tableau de String ou d'Objet.

Dim mois(11) As String

'mois (1) contient Nothing

mois(0)="Janvier"

mois(1)="Février"

mois(2)="Mars"

ou  lors de sa déclaration :

Dim Mois() As String ={Janvier,Février,Mars}

On remarque ici, que le nom d'élément n'est pas indiqué; comme on initialise 3 éléments, le tableau en aura 3.

On verra dans un des exemples que l'on peut créer un tableau avec la méthode CreateInstance. 

 

Autre syntaxe:

Dim t As String()    'déclaration

t = New String(1) {"One", "Two"} ' on affecte au tableau un nouveau tableau de String contenant "One" et "Two"

 

Dim R(,) as Integer ={{0, 1}, {1, 2}, {0, 0}, {2, 3}}

On déclare et on initialise en même temps un tableau à 2 dimensions, remarquez qu'on rentre les éléments 2 à 2.(Équivalent à R(0,0)=0  R(0,1)=1  R(1,0)=1  R(1,1)=2   ..)

Redim permet de redimensionner un tableau (modifier le nombre d'éléments d'un tableau existant), si on ajoute Preserve les anciennes valeurs seront conservées.

Attention , on ne peut pas modifier le nombre de dimension, ni le type des données. Un tableau à 2 dimensions de 20 fois 20 string pourra être redimensionné en tableau de 30 fois 30 String, mais pas en tableau d'entiers ou à 3 dimensions.

Dim T(20,20) As String

...

Redim Preserve T(30,30)

 

Il est possible d'écrire Dim T( , ) As String

Dim T( , ) As String  'Sans donner les dimensions du tableau: 

Il est déclaré mais n'existe pas car T(1,1)="toto" déclenche une erreur. 

Il faut avant de l'utiliser écrire Redim T(30,30), (sans remettre As String).

Certaines instructions comme Split redimensionne elle-même le tableau au nombre d'élément nécessaire.

Dim Nom() as String

Nom=S.Split(Separateur)

 

 

Erase efface le tableau et récupère l’espace.

Erase Tableau  (équivalent à tableau= Nothing )

 

Clear réinitialise le tableau. (remise à 0 d'un tableau de numérique par exemple)

Array.Clear(t, 2, 3)  réinitialisation tableau t à partir de l'élément 1 et pour 3 éléments.

 

 

Comment parcourir un tableau?

Pour parcourir un à un tous les éléments d'un tableau, on utilise une boucle:

Exemple: créer un tableau de 11 éléments et mettre 0 dans le premier élément, 1 dans le second, 2 dans le troisième...

Dim T(10) As Integer

Dim i As Integer

 

For i = 0 To 10    'Pour i allant de 0 à 10

         T(i)=i

Next i

La variable de boucle i est utilisée pour parcourir le tableau: on utilise l'élément T( i ) donc successivement T(1) puis T(2)...et on affecte i donc 1 puis 2 puis 3..

 

On peut aussi utiliser For Each:( un tableau hérite de la classe System.Array)

 

Dim amis() As String = {"pierre", "jean", "jacques", "toto"}

For Each nom As String In amis

    Console.Out.WriteLine(nom)

Next

L'exemple affiche sur la console (menu Affichage->Fenêtre->Sortie) les noms qui sont dans le tableau.

 

VB alloue de l'espace mémoire pour chaque élément crée. Ne dimensionnez pas un immense tableau si vous avez besoin d'un tableau de 4*4 car cela utilise de la mémoire inutilement.

 

Un tableau est un objet !!

Créons 2 tableaux et examinons les principales méthodes.

Dim a(3) As String

Dim b(3) As String

b=a         Copie le tableau a dans b

b=a.copy    Est équivalent

Attention: il copie les références (l’adresse, l’endroit ou se trouve la variable) et non pas la valeur de cette variable, ce qui fait que si vous modifiez b(3), a(3) sera aussi modifié.

Car lorsque vous assignez une variable tableau à une autre, seul le pointeur (l’adresse en mémoire) est copié.

 

Pour obtenir une copie ‘indépendante’ faire :

b=a.clone

Dans ce cas si vous modifié a(2), b(2) ne sera pas modifié.

 

Par contre a(1)=b(1) n'affecte que l'élément a(1) 

 

La Classe Array.

Tous les tableaux viennent de la classe Array; vous pouvez accéder aux méthodes et propriétés de System.Array de chaque tableau Par exemple, la propriété Rank retourne le nombre de dimension du tableau et la méthode Sort trie ses éléments.

Exemple :

Soit un tableau Mois()

Clear

Array.Clear(Mois,0,2)  Efface 2 éléments du tableau Mois à partir de l’élément 0

Reverse

Array.Reverse(Mois, 1, 3) inverse les 3 éléments à partir de l’élément 1

Copy

Array.Copy(Mois,1,Mois2,1,20) copie 20 éléments de Mois vers Mois2 à partir du 2eme élément.

Sort

Array.sort(Mois)    Trie le tableau Mois

Malheureusement cette méthode marche sur des tableaux unidimensionnels uniquement.

Au lieu d'utiliser un tableau à 2 dimensions  (sur lequel la méthode 'Sort' ne marche pas, on peut ruser et créer 2 tableaux et surcharger la méthode sort pour trier les 2 tableaux (un servant de clé, le second d'items):

Array.Sort(myKeys, myValues) (Voir un exemple plus bas)

 

Equals   compare 2 tableaux.

 

Binarysearch recherche un élément dans un tableau trié unidimensionnel.(algorithme de comparaison binaire performant sur tableau trié)

Exemple :

I=Array.BinarySearch(Mois, "Février")  retourne I=1  se souvenir le premier élément est Mois(0)

BinarySearch effectue une recherche dichotomique: il regarde l'élément du milieu, si l'élément cherché est plus petit, il regarde l'élément du milieu du haut du tableau.....

C'est rapide mais le tableau doit être trié.

S'il trouve un élément il retourne sous index.

Si la recherche échoue, il retourne un nombre négatif, si on effectue un Not sur ce nombre retourné, on a l'index où on doit insérer l'élément

IndexOf

Recherche un objet spécifié dans un tableau unidimensionnel (trié ou non), retourne l'index de la première occurrence.

Dim myIndex As Integer = Array.IndexOf(myArray, myString)
 

Retourne -1 si l'élément n'est pas trouvé.

LastIndexOf fait une recherche à partir de la fin.

Ici la recherche est linéaire: on compare l'élément recherché avec le premier puis le deuxième, puis le troisième élément... C'est long , mais le tableau n'a pas besoin d'être trié.

On a probablement intérêt à trier le tableau et à faire un Binarrysearch. (Cela se dit mais je ne l'ai pas vérifié)

Ubound

Retourne le plus grand indice disponible pour la dimension indiquée d'un tableau.

Dim Indice, MonTableau(10, 15, 20)
Indice = UBound(MonTableau, 1)
  Retourne 10. (1 indique la première dimension du tableau)
 

GetUpperBound même fonction

Indice = MonTableau.GetUpperBound(0) ( 0 pour première dimension!!) Retourne 10.

 

Lbound existe (plus petit indice) mais est inutile car toujours égal à 0.

 

Length  retourne un entier qui représente le nombre d'éléments total dans le tableau.

 Pour un tableau à une dimension Lenght-1 retourne l'indice du dernier élément.

 Cela est souvent utilisé pour parcourir tous les éléments du tableau:

 Dim t(10) As String

 Dim i As Integer

 For i = 0 To t.Lenght-1

   t(i)=..

 Next t

On remarque que dans un tableau multi dimension Lenght n'est pas égal à Ubound

GetLength(x)  retourne un entier qui représente le nombre d'éléments dans la dimension x.

GetValue et SetValue permettent de connaître ou de modifier la valeur d'un élément du tableau:

Mois.GetValue(0)  est équivalent à  Mois(0)

Dans un tableau à 2 dimensions comment modifier l'élément (0,3):  

myArray.SetValue("fox", 0, 3)

C'est équivalent à myArray(0,3)="fox"

 

ArraySegment  permet de définir un segment, une plage dans  une Array.(framework 2)

Dim myArrSegMid As New ArraySegment(Of String)(myArray, 2, 5) 'ici le segment débute au second élément et contient 5 éléments.

(Si on modifie un élément de  myArrSegMid cela modifie myArray car le segment définie une plage du tableau et non un nouveau tableau)

 

Sur des tableaux, les actions à effectuer sont principalement:

Rechercher un élément.

Trier le tableau.

Insérer un élément.

Enlever un élément.

On a déjà évoqué cela , mais pour étudier le détail voir les tableaux et collections
 

 

Pour les super pro (débutant passe ton chemin), on peut utiliser des méthodes génériques.

Exemple recherche dans un tableau de short nommé monTab l'élément 2

index= Array.indexOf (Of Short)(monTab, 2) est hyper plus rapide que

index= Array.indexOf (monTab, 2) car la première version avec généric est directement optimisée pour les Short.

Il est est de même pour Binarysearch et Sort.

Cela est valable pour les types 'valeur' (peu d'intérêts pour les strings par exemple).

 

Exemple:

Exemple détaillé:

Créer un tableau de 6 éléments, mettre dans chaque élément du tableau le carré de son indice, afficher le contenu du tableau.

Cela montre l’intérêt d’utiliser une boucle pour balayer tous les éléments d’un tableau. Première boucle pour remplir le tableau, seconde boucle pour afficher.(Une boucle For ..Next est ici utilisée, on verra cela plus loin.) 

 

      Dim arr(5) As Integer

      Dim i As Integer

      For i = 0 To arr.GetUpperBound(0)’ GetUpperBound(0) retourne 5

         arr(i) = i * i

      Next i

 

     For i = 0 To arr.GetUpperBound(0)

         Console.WriteLine("arr(" & i & ") = " & arr(i))

      Next i

 

Faire une boucle allant de 0 au dernier élément du tableau (For i=0 to ..)

Dans chaque élément du tableau mettre le carré de son indice (arr(i)=i*i )

Nouvelle boucle pour afficher les noms des différents éléments et leur contenu. (Console.WriteLine() affiche sur la console le nom de l'élément et son contenu)

 

Le programme génère la sortie suivante :

arr(0) = 0

arr(1) = 1

arr(2) = 4

arr(3) = 9

arr(4) = 16

arr(5) = 25

 

Exemple de recherche dans un tableau:

Dans un tableau de String rechercher dans quel élément et à quelle position se trouve la string "MN".

Dim Tableau() As String = {"ABCDEFG", "HIJKLMNOP"}
Dim AChercher As String = "MN"
Dim i As Integer
Dim position As Integer
For i = 0 To Tableau.Length - 1
'on parcourt chaque élément du tableau
    position = Tableau(i).IndexOf(AChercher)
'dans l'élément  du tableau on cherche la sous-chaîne
    If position >= 0 Then Exit For
Next i

 

Exemple de tri de 2 tableaux:

On crée un tableau de clés et un tableau des valeurs, à chaque clé est liée une valeur.

On trie à partir du tableau des clés myKeys , le tableau myValues est modifié pour 'suivre' le tri des clés. La Sub PrintKeysAndValues affiche les résultats.

Public Shared Sub Main()

' ****************Création des tableaux.

Dim myKeys() As String = {"red", "GREEN", "YELLOW", "BLUE", "purple", "black", "orange"} 'Tableau des clé

Dim myValues() As String = {"strawberries", "PEARS", "LIMES", "BERRIES", "grapes", "olives", "cantaloup"} 'tableau des éléments

 

'Affichage du tableau non trié

Console.WriteLine("Tableau non trié:")

PrintKeysAndValues(myKeys, myValues)

' Tri les éléments 1 à 3 puis affichage.

Array.Sort(myKeys, myValues, 1, 3)

Console.WriteLine("Après tri d'une partie du tableau:")

PrintKeysAndValues(myKeys, myValues)

    ' Tri la totalité du tableau.

Array.Sort(myKeys, myValues)

Console.WriteLine("Après tri de la totalité du tableau:")

PrintKeysAndValues(myKeys, myValues)

End Sub 'Fin de Main

 

    ' Routine affichant dans la console les clés et valeurs

Public Shared Sub PrintKeysAndValues(ByVal myKeys() As [String], ByVal myValues() As [String])

Dim i As Integer

For i = 0 To myKeys.Length - 1

    Console.WriteLine(" {0,-10}: {1}", myKeys(i), myValues(i))

Next i

Console.WriteLine()

End Sub 'PrintKeysAndValues

 

Création de tableau avec CreatInstance

' Créons un tableau d'entier (Int32) comprenant 5 éléments.
Dim myArray As Array = Array.CreateInstance(GetType(Int32), 5)
Dim i As Integer
For i = myArray.GetLowerBound(0) To myArray.GetUpperBound(0)
    myArray.SetValue(i + 1, i)
Next i

 

Merci Microsoft pour les exemples.

 

On insiste donc sur le fait qu'un tableau est de type 'par référence' ( et pas ''par Valeur'), on y reviendra.