# Environnements de dveloppement > Delphi > Codes sources  tlcharger >  [FMX] Implmentation de MapReduce

## gbegreg

Bonjour,

Dans cet exemple, je vous propose une implmentation des mthodes map, reduce, filter que l'on retrouve dans d'autres langages (essentiellement fonctionnels).

Pr-requis vous devez avoir au minimum Delphi 10.3 (Rio). En effet, j'ai dvelopp cet exemple avec Delphi 11 et j'ai utilis les gnriques (disponibles  partir de Delphi 2009)  et les variables inline et l'infrence de type (disponibles  partir de Delphi 10.3 il me semble).
Le projet exemple fourni est ralis avec FMX mais l'unit GBEArray.pas peut tre utilise en VCL galement.

Explications
Trs brivement, je vais dtailler les rles de ces 3 mthodes.
La mthode *map* permet  partir d'un tableau et d'une fonction anonyme passe en paramtre, de crer un nouveau tableau de la mme taille que le tableau d'origine mais en appliquant la fonction anonyme  tous les lments du tableau. La mthode map est souvent compare  une boucle for.
La mthode *filter* permet  partir d'un tableau et d'une fonction anonyme passe en paramtre, de crer un nouveau tableau de taille infrieure ou gale au tableau d'origine. La mthode anonyme passe en paramtre permet de filtrer et de ne conserver que les lments souhaits du tableau d'origine. Le nouveau tableau rsultant est donc trs souvent de taille plus petite que le tableau d'origine. C'est l'objectif du filtre.
La mthode *reduce* permet  partir d'un tableau et d'une fonction anonyme passe en paramtre, de crer un unique lment (donc pas un tableau) qui agrge des informations du tableau d'origine  l'aide de la fonction anonyme passe en paramtre.

Exemple
Si vous n'tes pas familier des langages fonctionnels (comme moi), vous pouvez vous demander quel est l'intrt de ces mthodes. Nous allons voir cela dans le projet exemple joint  ce post.
Dans le projet joint, vous trouverez l'unit GBEArray.pas qui contient l'implmentation de ces mthodes plus deux autres Sort et Print.
Un petit mot sur ces deux mthodes. Comme je manipule des objets de type TArray, il pouvait tre utile d'utiliser leur mthode "sort" pour trier le tableau : d'o 'ajout de la mthode sort au TGBEArray. La mthode Print sert  afficher ( l'aide d'une fonction anonyme passe en paramtre) tous les lments du tableau. Elle m'a servit au debug et je l'ai laisse.

Le programme exemple fourni lui aussi dans le zip se prsente de la manire suivante :


Le bouton "*Initialiser*" permet d'initialiser une liste alatoire de 20 entiers affichs dans la liste de gauche. Cela permet d'initialiser un tableau d'entier pour tester les mthodes map, reduce et filter.

Le bouton "*Map (x2)*" permet de lancer l'excution de la mthode map sur ce tableau en passant en paramtre la fonction anonyme :


```

```

qui va permettre de multiplier par 2 chaque lment du tableau. Le rsultat est est un nouveau tableau affich dans la listbox2 (celle de droite).

Le bouton "*Filter (>20)*" permet de lancer l'excution de la mthode filter sur le tableau d'origine en passant en paramtre une fonction anonyme qui indiquera qu'il ne faut conserver que les lments dont la valeur est > 20.

Le bouton "*Reduce (valeur init 0)*" permet de lancer l'excution de la mthode reduce sur le tableau d'origine en passant en paramtre une fonction anonyme qui permettra d'additionner les valeurs des diffrents lments du tableau. La valeur initiale est un second paramtre de la mthode reduce qui permet de prciser une valeur initiale au calcul (dans notre cas 0 car on souhaite calculer la somme de tous les entiers du tableau).

Le bouton "*Tri*" permet de lancer l'excution de la mthode sort sur le tableau d'origine ce qui produira un nouveau tableau avec les lments du tableau d'origine tri. A noter, il est possible de passer un TComparer pour spcifier le tri que l'on souhaite faire sur des tableau de types plus complexes qu'un tableau d'entier (voir aprs  :;):  )

L o a devient intressant, c'est que les mthodes map, reduce, filter, sort et print peuvent s'enchainer indfiniment... Le bouton "*Map x2, Filter >100 puis Reduce*" montre cela car il enchaine :
- un appel  map en multipliant les valeurs par 2
- puis, un appel  filter pour ne conserver que les lments dont la valeur obtenue est > 100
- puis un appel  reduce pour calculer la somme des valeurs obtenues

Enfin, le bouton "*Exemple sur objets*" est un exemple avec un tableau d'objet complexe (TPersonne fourni dans l'unit uPersonne.pas). Je cre un jeu d'essai dynamiquement de 10 personnes, puis j'utilise la mthode print pour simplement afficher ce jeu d'essai dans la liste 1, puis appel  filter pour ne slectionner que les personnes dont le genre est renseign, puis appel  map pour affecter  ces personnes un nombre de points alatoire, puis appel  sort (avec utilsation d'un TComparer) pour trier le tableau obtenu par ordre dcroissant des points, puis print pour afficher le rsultat dans la liste 2 et enfin appel  reduce pour calculer le nombre de points total attribu.
Voici le rsultat :


Voici le zip du projet : MapReduce.zip

----------


## Paul TOTH

Hello, deux petites remarques sur ton code

1) les rallocations

dans initialiserList2 tu utilises "monTableau := monTableau + [StrToInt(s)];" c'est fonctionnel, mais cela implique  chaque itration une rallocation de monTableau pour avoir un lment de plus...selon le gestionnaire mmoire en place a ne sera pas systmatique (allocation d'une zone plus grande que demande selon le gestionnaire), mais ce n'est pas optimal.

il est prfrable de prallouer le tableau quand on en connait la taille car l'allocation mmoire est un process couteux en temps de calcul


```

```

mme remarque pour l'unit GBEArray; pour Filter il est prfrable d'allouer un premier tableau de la taille de Data puis de le rduire  la taille rellement utile...dans le pire des cas on aura une grosse allocation pour rien, mais a restera 2 allocations, alors que par iteration sur un trs gros tableau tu auras tout un tas d'allocation mmoire.

2) petit dtail, mais dans la mthode Print tu retournes un nouveau TGBEArray<T> alors que tu pourrais retourner Self...au final a ne change pas grand chose vu Delphi va faire la copie lui mme puisqu'on est sur des Record et pas des Objets...mais dans l'ide, on est suppos retourner Self car Data n'est pas modifi  ::):

----------


## gbegreg

Bien vu Paul  ::): 

Voici la version corrige : MapReduce_v2.zip

Pour la fonction Print,  l'origine c'tait un copier/coller de la fonction map qui ne devait pas rester mais je la trouve finalement pratique.

----------


## gbegreg

Bonjour,

Voici une V3 du projet : MapReduce_v3.zip

Cette version apporte de nouvelles mthodes au TGBEArray : 
- any : elle prend une fonction anonyme en paramtre. Son objectif et de renvoyer un boolean indiquant s'il y a au moins un lment du tableau qui correspond au(x) critre(s) dfini(s) dans la fonction anonyme);
- concat : elle prend un autre TGBEArray<T> en paramtre et permet de concatner son contenu au TGBEArray d'origine;
- gather : elle prend une fonction anonyme en paramtre et une chaine de caractres (qui servira de sparateur). Son objectif est de gnrer un nouveau TGBEArray<string> qui permet de dfinir des couples cls/valeurs et qui regroupe les cls identiques afin qu'il n'y ait plus de doublon sur ces cls. Les valeurs peuvent alors tre la concatnation des valeurs des cls identiques, leurs sommes... C'est la fonction anonyme qui indiquera le traitement  effectuer.

J'ai mis  jour l'application exemple en ajoutant des exemples pour ces nouvelles fonctionnalits :


Les boutons sont regroups dans des cadres colors.
Le cadre bleu contient les boutons pour lancer les actions sur un tableau de valeurs entires gnr alatoirement. Il faut cliquer sur le bouton Initialiser pour gnrer ce jeu de donnes. Le jeu de donnes sera gnr dans la listbox1. Les autres boutons du cadre bleu prendront ce jeu de donnes pour raliser leurs actions. Les rsultats des traitements seront affichs dans listbox2.
Le cadre violet est un essai avec un tableau d'un type plus complexe TPersonne. En cliquant sur le bouton correspondant, un jeu de donnes sera aussi gnrs dans listbox1 et le rsultat des traitements sera affich dans listbox2.
Enfin, le cadre jaune contient un TMemo contenant un texte exemple mais il est possible de l'diter  sa convenance. Le clic sur le bouton de ce cadre va dclencher un traitement qui va lister les mots composants le texte du TMemo et pour chaque mot, compter le nombre d'occurrences de celui ci dans le texte. Un tri est effectu en fin de traitement afin de trier le rsultat par ordre alphabtique des mots. Le rsultat est affich dans la listbox2.

Cela permet de voir de nouveaux exemples sur les possibilits de TGBEArray.

----------


## gbegreg

Pour information, j'ai mis le projet MapReduce sur mon GitHub : https://github.com/gbegreg/MapReduce
Il y a dj une petite volution suite  une remarque : les mthodes map et reduce peuvent maintenant avoir des types d'entre et de sortie diffrents.

Les futures volutions de ce projet seront faites sur le GitHub  ::):

----------


## SergioMaster

Bonjour,
en fait ce n'est pas pour critiquer le projet, mais le titre que j'mets cette note. 

MapReduce, tu m'as tellement habitu  la 3D qu'au dpart je n'ai mme pas regard que le code n'tait pas sur un dessin de carte que je cochai lu sans mme regarder !  ::oops:: 

puis-je suggrer quelque chose de plus explicite comme : 'Ajout des fonctions map, reduce et filter  un tableau'

----------


## gbegreg

Bonjour Serge,

a change un peu, il n'y a pas que la 3D  ::): 

Par contre, il y aura certainement bientt un nouveau petit sujet sur la 3D...

----------

