web-dev-qa-db-fra.com

Existe-t-il un modèle de choix d'un ensemble d'options au hasard lorsque leurs critères de sélection sont égaux?

Je souhaite choisir entre plusieurs options et si les critères que j'utilise pour la sélection sont égaux, j'en veux un au hasard (raisonnablement ainsi, il est donc donc égal de chance à chaque fois, plutôt que d'arbitraire). Cela se fait facilement avec des ifs imbriqués, mais cela devient assez moche et finit par faire du code de duplication.

Un exemple de cas simplifié, au cas où cela n'est pas clair.

extern crate Rand;

fn main() {
    let a = 5;
    let b = 5;

    if a > b {
        println!("Do the thing where a is bigger");
    } else if b < a {
        println!("Do the thing where b is bigger");
    } else { 
        if Rand::random::<bool>() {
            // I don't want to duplicate the code here!
            println!("Do the thing where a is bigger");
        } else {
            // Or here!
            println!("Do the thing where b is bigger");
        }
    }

}

( Terrain de jeux de rouille )

Y a-t-il un meilleur moyen de le faire, ce qui ne nécessite pas de duplication de code? Dans cet exemple simplifié, je ne choisis que entre deux possibilités, mais cela pourrait réellement être une liste plus longue. (Qu'en est-il d'agir basé sur le plus haut de a, b, c, d, où il est possible qu'il y ait un deux, trois ou quatre cravate?)

J'arrive à apprendre Rust Donc, s'il y a des fonctionnalités de langue intelligentes qui seraient cooles, mais je suis également intéressé par le cas général si possible.

3
mattdm

Une première pratique générale est de réduire la duplication à l'aide de la décomposition fonctionnelle. Cela signifie la décomposition d'une fonction complexe en parties plus simples et potentiellement réutilisables. Votre code dupliquerait ensuite uniquement les appels de fonction:

fn do_a() {
    println!("Do the thing where a is bigger");
}
fn do_b() {
    println!("Do the thing where b is bigger");
}
fn main() {
    ...

    if a > b {
        do_a();
    } else if b < a {
        do_b();
    } else { 
        if Rand::random::<bool>() {
            do_a();
        } else {
            do_b();
        }
    }
}

Un moyen plus efficace est de refactoriser le code consolider les expressions conditionnelles; Je ne connais pas la rouille, alors excuse toutes les erreurs de langue, mais ce serait quelque chose comme:

fn main() {
    let a = 5;
    let b = 5;

    let agb = if a==b { Rand::random::<bool>() } else { a>b };
    if agb {
        do_a();
    } else {
        do_b();
    }
}
5
Christophe