Intéressé par des cours d'informatique en ligne ?
Visitez mon nouveau site https://www.yesik.it !

Vous connaissez les tableaux. Ils permettent de mémoriser une collection d'objets et d'y accéder par leur index. Un tableau associatif fait sensiblement la même chose, mais au lieu d'utiliser des index numériques pour retrouver les valeurs, il permet d'utiliser n'importe quel autre type de donnée. Dans ce contexte, on parle de clé plutôt que d'index.

Un exemple

Notre programme d'exemple sera un logiciel de traduction . Celui-ci est capable de faire la traduction d'une phrase du français à l'anglais.

Ce programme est extrêmement rudimentaire, puisqu'il effectue une traduction mot-à-mot. Autrement dit, il possède un "dictionnaire" de correspondance français-anglais, et l'utilise pour traduire chaque mot de la phrase.

Pseudo-code

En pseudo-code, cela s'exprime:

chaque Traducteur
    sait que traduire un texte c'est:
        définir dictionnaire ← {
            "le" : "the",
            "la" : "the",
            "chat" : "cat",
            "mange" : "eats",
            "souris" : "mouse",
            "fromage" : "cheese"
        }
        pour chaque mot du texte faire:
            afficher dictionnaire[mot]

Le programme principal fait:
    définir traducteur ← nouveau Traducteur
    demande au traducteur de traduire("le souris mange le fromage")
    demande au traducteur de traduire("le chat mange la souris")

Le point essentiel de ce programme est bien sûr le dictionnaire. Celui-ci est un tableau associatif qui fait correspondre un mot en anglais (la valeur) à un mot en français (la clé).

Cette correspondance est utilisée sur la ligne:

            afficher dictionnaire[mot]

Comme vous le constatez, un tableau associatif se manipule comme un tableau ordinaire. La seule différence étant que les index, appelés clés dans ce contexte, ne sont pas numériques.

PHP

La structure du programme est des plus classiques:

<?php
 
class Traducteur {
    public function traduire($texte) {
        /* TODO: à définir */
    }
}
 
$traducteur = new Traducteur();
$traducteur->traduire("la souris mange le fromage");
$traducteur->traduire("le chat mange la souris");

Comme vous le remarquez, la méthode traduire reçoit en paramètre le texte à traduire:

    public function traduire($texte)

Un paramètre se comporte exactement comme une variable locale, à ceci près qu'elle est initialisée au moment de l'appel de la méthode:

$traducteur->traduire("le chat mange la souris");
$traducteur->traduire("la souris mange le fromage");

Dans le premier des deux appels ci-dessus, la méthode traduire s'exécute avec le paramètre $texte initialisé à "le chat mange la souris". Et lors du second appel, la même méthode s'exécute avec $texte initialisé à "la souris mange le fromage".

Détaillons maintenant le contenu de cette méthode traduire. Celle-ci nécessite un tableau associatif.

Or, PHP supporte au niveau du langage les tableaux associatifs. La syntaxe ressemble fortement à celle des tableaux ordinaires. Ainsi pour créer un tableau on utilise toujours la fonction PHP array, mais en précisant la clé associée à chaque valeur:

$tableau = array(
              cle1 => valeur1,
              cle2 => valeur2,
              /* et ainsi de suite */
            );

La structure de contrôle foreach permet aussi de récupérer (si nécessaire), la clé en même temps que la valeur:

foreach($tableau as $cle => $valeur) {
    /* ... */
}

Remarque:

En réalité, en PHP, tous les tableaux PHP sont des tableaux associatifs!

Ainsi, quand vous définissez le tableau suivant:

$beegees = array(
              "Barry", 
              "Robin", 
              "Maurice"
          );

C'est comme si vous définissez en réalité le tableau associatif équivalent:

$beegees = array(
              0 => "Barry", 
              1 => "Robin", 
              2 => "Maurice"
          );

Concrètement, pour en revenir à notre exemple, le dictionnaire est définit ainsi:

public function traduire($texte) {
        $dictionnaire = array(
            "le"        => "the",
            "la"        => "the",
            "chat"      => "cat",
            "souris"    => "mouse",
            "mange"     => "eats"
        );
/* ... */

Notre second problème, est de séparer le texte en mot. Nous allons pour cela utiliser la fonction PHP split. Celle-ci transforme une chaîne de caractères' en tableau contenant une entrée pour chaque élément de la chaîne. Ainsi pour parcourir chaque "mot de la chaîne", on peut écrire:

public function traduire($texte) {
        /* ... */
 
        foreach(split("[^A-Za-z]", $texte) as $mot) {
            /* TODO: traiter chaque mot */
        }
 
/* ... */

Reste à écrire le corps de la boucle ci-dessus. Celui-ci se résume à trouver – et afficher – la traduction du mot. Ce qui se fait avec l'instruction:

print $dictionnaire[$mot];

Après une ou deux modifications visant à améliorer l'affichage, voici le code complet de la méthode traduire:

/* ... */
    public function traduire($texte) {
        $dictionnaire = array(
            "le"        => "the",
            "la"        => "the",
            "chat"      => "cat",
            "souris"    => "mouse",
            "mange"     => "eats"
        );
 
        foreach(split("[^A-Za-z]", $texte) as $mot) {
            print $dictionnaire[$mot] . " ";
        }
        print("\n");
    }

Groovy

Après ces longues explications pour quelque-chose de finalement pas très compliqué à comprendre, nous allons plus rapidement passer sur la version Groovy de ce programme.

Tout comme PHP, Groovy supporte directement la notion de tableau associatif au niveau du langage. C'est à dire qu'il y a directement des constructions syntaxiques pour créer et utiliser les tableaux associatifs.

Bien sûr, la syntaxe est quelque peu différente de celle de PHP. Mais je pense que vous êtes assez observateur pour les identifier.

Voici donc le code Groovy correspondant à notre programme de traduction:

class Traducteur {
    public traduire(texte) {
        def dictionnaire = [
            "le" : "the",
            "la" : "the",
            "chat" : "cat",
            "mange" : "eats",
            "souris" : "mouse",
            "fromage" : "cheese"
        ];
 
        for(mot in texte.split('[^A-Za-z]')) {
            print(dictionnaire[mot] + " ");
        }
        println();
    }
 
    static main(args) {
        def traducteur = new Traducteur();
        traducteur.traduire("la souris mange le fromage");
        traducteur.traduire("le chat mange la souris");
    }
}

La manipulation du tableau associatif n'a rien de plus complexe qu'en PHP. Quand à la séparation du texte en mots, elle utilise la version Java de la méthode split. A nouveau, si vous en avez compris le fonctionnement en PHP, rien de mystérieux ici.

Java

Avec Java, nous abandonnons les langages qui supportent les tableaux associatifs au niveau du langage. Ainsi, en Java il est nécessaire d'utiliser une instance de l'interface Map pour les manipuler. Ainsi, voyons comment créer un tableau associatif en Java:

Map<String, String>     dictionnaire = new HashMap<String, String>();

Cette instruction se contente de créer un nouveau tableau associatif. La notation est complexe car il est nécessaire d'indiquer au compilateur le type de la clé (ici String) et celui de la valeur associée (ici String également).

Remarque:

Vous remarquez également que le type de la variable dictionnaire est Map alors que l'opérateur new crée une instance de la class HashMap.

L'explication est que Map est juste une interface. C'est à dire qu'elle déclare ce que peut faire n'importe quel tableau associatif, mais ne définit concrètement aucune de ces méthodes. Leur mise en oeuvre est déléguée à d'autres classes. HashMap est une de ces classes qui met en oeuvre l'interface Map.

Cela permet une grande souplesse de programmation: ainsi, le programmeur choisit quel sorte de Map il veut créer lors de la création du tableau associatif. Ensuite, tous les traitements appliqués à ce tableau se font sans avoir à faire référence à cette classe réelle, mais toujours à son interface Map.

Ainsi, par exemple, si pour une raison ou une autre on décide de changer le type réel du tableau associatif, il suffit de changer la ligne qui crée le tableau associatif. Et rien d'autre dans le programme.

Maintenant que la tableau associatif est créé, reste à le peupler. Cela se fait par la méthode java.util.Map.put:

/* ... */
        dictionnaire.put("le", "the");
        dictionnaire.put("la", "the");
        dictionnaire.put("chat", "cat");
        dictionnaire.put("mange", "eats");
        dictionnaire.put("souris", "mouse");
        dictionnaire.put("fromage", "cheese");
/* ... */

Le reste du code est très similaire à la version Groovy. Et utilise en particulier la méthode split pour découper le texte en mots. Quand à récupérer la valeur associée à une clé dans le dictionnaire, cela se fait grâce à la méthode java.lang.Map.get:

/* ... */
        for(String mot : texte.split("[^A-Za-z]")) {
            System.out.print(dictionnaire.get(mot) + " ");
        }
/* ... */


Au final, le programme complet est le suivant:

import java.util.Map;
import java.util.HashMap;
 
public class Traducteur {
    public void traduire(String texte) {
        Map<String, String>     dictionnaire = new HashMap<String, String>();
        dictionnaire.put("le", "the");
        dictionnaire.put("la", "the");
        dictionnaire.put("chat", "cat");
        dictionnaire.put("mange", "eats");
        dictionnaire.put("souris", "mouse");
        dictionnaire.put("fromage", "cheese");
 
        for(String mot : texte.split("[^A-Za-z]")) {
            System.out.print(dictionnaire.get(mot) + " ");
        }
        System.out.println();
    }
 
    public static void main(String[] args) {
        Traducteur traducteur = new Traducteur();
        traducteur.traduire("la souris mange le fromage");
        traducteur.traduire("le chat mange la souris");
    }
}

A vous de jouer

On souhaite écrire un programme Java d'aide à la manière du man Unix, mais pour les fonctions PHP (par exemple, celles que vous trouverez à l'adresse http://www.php.net/manual/en/ref.strings.php)

On souhaite pouvoir utiliser ce programme de la manière suivante:

sh$ java PHPHelp explode
Split a string by string
array explode  ( string $delimiter  , string $string  [, int $limit  ] )
sh$ java PHPHelp fprintf
Write a formatted string to a stream
int fprintf  ( resource $handle  , string $format  [, mixed $args  [, mixed $...  ]] )

Vous utiliserez un tableau associatif pour faire correspondre une description avec un nom de fonction.