Malgré son approche un peu alambiquée, ce que ton code essaie manifestement de faire est le rapprochement entre les éléments de deux listes. Ce n'est pas vraiment nouveau comme algorithme et on appelle parfois cela un zip.
Comme il a été dit, pas besoin de deux boucles imbriquées, juste une qui accède aux éléments de chaque liste. Avec des tableaux ou des listes, un simple index suffit. Cela ammène cependant un première question : que doit-on faire si les deux listes n'ont pas la même longueur ? On peut s'arrêter à la plus courte, généralement l'approche par défaut. S'il est impératif que les deux listes soint de la même longueur, alors il faut déclencher une erreur.
Ensuite sur la combinaison elle-même, un autre problème se présente. Tu fais une division d'un entier par un entier. Or l'entier diviseur peut être égal à 0, ce qui est une opération illégale et lèvera une exception. Il faut donc savoir comment tu veux gérer ce potentiel problème :
- laisser tel quel, la division par 0 lèvera une exception ;
- contrôler et lever une exception spécifique portant sur le jeu données lui-même plutôt que sur l'opération mathématique if(right[i] == 0) throw new ArgumentException($"Unexpected 0 value at index {i} in divisor data source"); ;
- contrôler et ignorer le calcul si le diviseur vaut 0 ;
- contrôler et renvoyer null, ce qui implique que toutes les valeurs renvoyées seront des Nullable<int> et donc que l'utilisateur de la fonction devra lui-même faire le tri dans les valeurs acceptables ;
- contraindre les valeurs en entrée en utilisant un type de donnée sur le second tableau qui garantit l'absence de valeur 0 (approche commune en programmation fonctionnelle).
En prenant le parti suivant :
- on limite le résultat à la plus petite des deux listes ;
- on renvoie des Nullable<int> avec null si l'opération est interdite.
Méthode visant à combiner deux entiers, en l'occurrence la division du premier par le second, avec en retour null si le diviseur vaut 0 :
static int? Combine(int left, int right) => right == 0 ? null : left / right;
Méthode qui prend deux listes en entrée et applique une fonction de combinaison pour produire un résultat :
1 2 3 4 5 6 7 8 9 10
| static List<int?> Combine(List<int> left, List<int> right, Func<int, int, int?> combiner)
{
int limit = Math.Min(left.Length, right.Length);
var result = new List<int>(limit);
for(int i = 0; i < limit; i++)
result[i] = combiner(left[i], right[i]);
return result;
} |
Exemple d'appel :
1 2 3 4
| List<int> List_01 = new List<int> { 14, 11, 32, 15 };
List<int> List_02 = new List<int> { 36, 17, 2, 3 };
List<int> result = Combine(List_01, List_02, Combine); |
Il est a noter que ce coode sera fonctionnellement similaire avec ce que l'on peut obtenir avec la méthode LinQ Enumerable.Zip :
1 2 3 4
| List<int> List_01 = new List<int> { 14, 11, 32, 15 };
List<int> List_02 = new List<int> { 36, 17, 2, 3 };
List<int> result = List_01.Zip(List_02, Combine).ToList(); |
Partager