par , 23/02/2025 à 11h31 (244 Affichages)
Le principe de la fonction récursive, a priori c'est simple, elle s'appelle jusqu'à un test d'échappement !
Voyons ça par un exemple simple, le calcul factoriel
La factorielle d'un nombre n est le produit des nombres entiers non nuls inférieurs ou égaux à n. La notation usuelle pour indiquer une factorielle est le point d'exclamation positionné après le nombre : la factorielle de n est notée n! => 4! = 1 x 2 x3 x 4 = 24
Pour calculer la factorielle d'un nombre il y a une fonction "Number.Factorial". La fonction récursive sera de calculer sur une liste de chiffres en paramètre, la factorielle à partir d'une position et pour une plage.
Déclarons une liste test {1..4} = {1, 2, 3, 4}
Quelle est la valeur si la position = 2 et la plage = 2 ? Solution Valeur en position 2 = 2 et plage = 2 > {2, 3} => Résultat 2 x 3 = 6
Quelle est la valeur si la position = 3 et la plage = 2 ? Solution Valeur en position 3 = 3 et plage = 2 > {3, 4} => Résultat 2 x 3 = 12
Quelle est la valeur si la position = 3 et la plage = 3 ? Solution Valeur en position 3 = 3 et plage = 2 > {3, 4,5} => Résultat = Plage trop grande
Le code maintenant
1 2 3 4 5 6 7 8 9 10 11 12 13
| Let
Source = {1..4},
fxFactorial = (lstpNum as list, ipIdxStart as number, ipLoop as number, optional ipResult as number ) =>
let
iResult = if ipResult = null then lstpNum{ipIdxStart-1} else lstpNum{ipIdxStart-1} * ipResult,
anyOut = if List.Count(lstpNum)> ipIdxStart + ipLoop -2 then
if ipLoop > 1 then @fxFactorial (lstpNum, ipIdxStart+1, ipLoop -1 , iResult) else iResult
else "Range too large"
in
anyOut ,
Factorial = fxFactorial(Source,3, 2)
in
Factoriall |
Source = {1..4}, //Déclaration de la liste de nombre pour simplifier l'exemple
- fxFactorial = (lstpNum as list, ipIdxStart as number, ipLoop as number, optional ipResult as number ) => // Déclaration de la fonction avec 4 paramètres
- lstpNum as list = La liste source
- ipIdxStart = La positon de départ. Attention les listes sont indexées à partir de 0 dans M. Donc la position 1 => Index = 0
- ipLoop = Plage de calcul
- ipResult = Résultat de la fonction à passer en paramètre qu'après un 1er calcul et pour une plage> 1
Le code
Remarques préalables :
- Pour appeler une fonction récursive, il faut la préfixer avec @ => @MaFonctionRecursive
- L'assignation à des variables nécessite la déclaration Let ... in
iResult = if ipResult = null then lstpNum{ipIdxStart-1} else lstpNum{ipIdxStart-1} * ipResult, // Multiplication de la valeur passée en paramètre x valeur de la liste en position -1 car indexation à 0
1 2 3
| anyOut = if List.Count(lstpNum)> ipIdxStart + ipLoop -2 then // Si le calcul est dans la plage alors
if ipLoop > 1 then @fxFactorial (lstpNum, ipIdxStart+1, ipLoop -1 , iResult) else iResult // Si nombre d'appels n'est pas atteint alors appel la fonction avec les paramètres reçus (+1 pour ipIdxStart, -1 pour ipLoop )
else "Range too large" // Message d'erreur si calcul hors plage |

C'est maintenant Votre Minute M