Un po ‘ doloroso tripla-nidificate operatore ternario

Sono andato alla ricerca attraverso Raphael.js‘s codice sorgente per scoprire come ha convertito i valori RGB per HSB. Ho trovato la funzione che ha fatto e sono stato nel processo di conversione di Python quando mi sono imbattuto in questo bel triplo nidificate operatore ternario:

H = (C == 0 ? null :
    V == r ? (g - b) / C :
    V == g ? (b - r) / C + 2 :
             (r - g) / C + 4
    );

Che mi ha buttato per un ciclo perché Python non hanno lo stesso tipo di operatore ternario che Javascript non. Ho trascorso un po ‘alla ricerca su di esso e, infine, hash con un po’ di sano codice (utilizzando solo if/else) al di fuori di esso:

if (C == 0) {
    H = null;
} else {
    if(V == r) {
        H = (g - b) / C;
    } else {
        if(V == g) {
            H = (b - r) / C + 2;
        } else {
            H = (r - g) / C + 4;
        }
    }
}

È stata la mia interpretazione è corretta? Sto solo chiedendo, perché se non è corretto, io sono di fronte a un sacco di debug. Così. Ho “capito”?

  • Sì, sembra che hai la logica di destra, a parte un paio di capitalizzazione discrepanze
  • il primo c a if(c == 0) dovrebbe essere una capitale c, no?
  • Eh, l’ho fatto? Mi sento come un lanciò un dardo su un bersaglio con il mio hinds legate dietro la schiena, gli occhi bendati, e ha segnato un bullseye. E sì, @NiftyDude, questo è corretto. Grazie per la cattura!
  • Sembra corretta. Dal momento che si sta convertendo a python, sono sicuro che non si cura in questo caso, ma è da notare che == in JavaScript non tipo di coercizione, così c’è la possibilità che i due siano diversi.
  • Sì, è vero. Grazie per la segnalazione.
  • Stai facendo il refactoring. Avere un paio di rappresentante di casi di test e di esecuzione di questi per verificare l’output è ciò che si desidera dopo la traduzione.
  • Naturalmente, grazie per il suggerimento. 🙂

 

6 Replies
  1. 26

    Penso che si può avere questo per evitare la profondità di annidamento:

    var H
    
    if(C == 0){
        H = null;
    }
    else if(V == r){
        H = (g - b) / C;
    }
    else if (V == g){
        H = (b - r) / C + 2;
    }
    else {
        H = (r - g) / C + 4;
    }
    • Perché non usare un bel truthy istruzione switch mentre che ci sei 😉
    • fai conto che questo è stato risposto 5 anni fa, giusto?
    • Ooh sì, lo so, 😎
  2. 25

    Per il mio gusto personale, un ben allineati nidificati ternario batte il se-esle pasticcio:

    const H =
      C == 0 ? null            :
      V == r ? (g - b) / C     :
      V == g ? (b - r) / C + 2 :
               (r - g) / C + 4 ;
  3. 6
    H = C == 0 
        ? null 
        : V == r 
            ? (g - b) / C 
            : V == g 
                ? (b - r) / C + 2 
                : (r - g) / C + 4

    Ho visto Dan Abramov utilizza questo rientro di collocamento modello. Mentre non mi piace come l’operatore condizionale ? più visivamente segue la condizione, io preferisco questa a qualcosa come @lolmaus l’esempio che il rientro sarà sempre costante indipendentemente dalle dimensioni del condizionale.

    Si effettivamente iniziare a guardare come ? vero : falso che è visivamente intuitivo qui. E in questo modo, trovo il ternario è molto più facile individuare e distinguere dalle circostanti codice.

  4. 5

    La stessa logica può essere scritto in un modo più semplice:

    var H
    
    if (C == 0)
        H = null;
    else if (V == r)
        H = (g - b) / C;
    else if (V == g)
        H = (b - r) / C + 2;
    else
        H = (r - g) / C + 4;

    È possibile omettere le parentesi graffe perché non c’è una singola istruzione in ogni condizione. E dato che le condizioni che si escludono a vicenda, utilizzando else if è molto più chiara di nidificazione ifs.

    • Molto interessante, grazie. Sono stato per lo più alla ricerca per la logica di convalida, però, cordiali saluti. 🙂
    • E ‘piuttosto ampiamente accettato che lo spazio/la”pulizia” di risparmio del non uso delle parentesi è fortemente compensato dalle conseguenze pericolose per la manutenibilità del codice. stackoverflow.com/a/2125078/205192
  5. 3

    Se JavaScript codebase nidificati ternario dichiarazioni come quella in questione, è consigliabile convertire la formattazione margherita ternario dichiarazioni invece.

    H = (C == 0)           //Is C zero?
        ? null
        : (V == r)         //Is V equal to r?
        ? (g - b) / C
        : (V == g)         //Is V equal to g?
        ? (b - r) / C + 2
        : (r - g) / C + 4; //Fallback (default) value

    Semplicemente leggere cima a fondo in una linea retta, la restituzione di un valore
    non appena hanno colpito un truthy condizione o riserva.

    Nidificato Ternaries sono Grandi, Eric Elliot

  6. 2

    Sì, è giusto (oltre capitalizzazione di differenze). Ancora, può essere cleaner scritto senza le parentesi, leggibile come elseif:

    if (C == 0)
        h = null;
    else if (V == r)
        h = (g - b) / C;
    else if (V == g)
        h = (b - r) / C + 2;
    else
        h = (r - g) / C + 4;
    • Dal momento che sarò la conversione di questo in Python, la sintassi non importa. Comunque grazie, però!
    • Penso che il python equivalente sarebbe elif… il punto che sembra che tutti si desidera fare è quello di evitare l’inutile rientro.
    • Che è corretto. E sì. Credo che se sei un programmatore il vostro istinto naturale è quello di fare qualcosa di leggibile… non si può incolpare nessuno per questo!
    • E ‘piuttosto ampiamente accettato che lo spazio/la”pulizia” di risparmio del non uso delle parentesi è fortemente compensato dalle conseguenze pericolose per la manutenibilità del codice. stackoverflow.com/a/2125078/205192
    • Non appena sarà seconda istruzione; l’unico scopo di questo codice è quello di assegnare a una variabile singola. Inoltre, l’OP è la conversione di questo Python dove non ci sono parentesi sono effettivamente applicate 🙂
    • Ah, giusto. Ho perso il suo parlare di python. Qualcuno dovrebbe risolvere la questione per rimuovere le parentesi graffe da l’esempio. Detto questo, anticipando che non ci sarà mai una seconda istruzione è un presupposto che si rivela sbagliato di nuovo e di nuovo e di nuovo…

Lascia un commento