Varietà di coding e di coding

Qualcuno sostiene che la programmazione è un arte e, in ultima analisi, non posso che essere d’accordo soprattutto quando si scovano soluzioni estremamente diverse per un medesimo problema. Per capire quanto sia vero questo, ecco come un’identica necessità nel medisimo linguaggio (Javascript) può essere risolta con approcci assolutamente diversi ed originali.

Left Pad zero

Un numero, ma il discorso è valido anche per una qualsiasi stringa, come 123 può essere riempito a sinistra – per pareggiarlo – con un certo numero di zeri, ad esempio: 00123. Questa necessità si presenta in varie occasioni e risulta utile per incolonnare – o comunque mostrare – un numero in maniera pulita, indicandone implicitamente il suo valore massimo. Nei videogame, ad esempio, il classico punteggio (lo score) viene spesso indicato con 001234, indicando che al massimo si arriverà a 999999. Ecco come lo stesso problema è stato risolto da vari sviluppatori:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
/**
 * Left Pad String
 *
 * @from          http://snipplr.com/view/8423/left-pad-string/
 * @author-web    http://www.mechanicmatt.com/
 *
 * @param         num         - Striga da riempire
 * @param         totalChars  - Numero totale di caratteri, comprensivo degli "zeri"
 * @param         padWidth    - Carattere usato per riempire, default "0"
 */

function leadingZeros(num, totalChars, padWith) {
    num = num + "";
    padWith = (padWith) ? padWith : "0";
    if (num.length < totalChars) {
        while (num.length < totalChars) {
            num = padWith + num;
        }
    } else {}

    if (num.length > totalChars) { //if padWith was a multiple character string and num was overpadded
        num = num.substring((num.length - totalChars), totalChars);
    } else {}

    return num;
}
alert(leadingZeros("asdf", 10, "0"));

Questa soluzione è estremamente articolata, tuttavia permette di aggiungere un numero indefinito di 0 al numero num scegliendo anche il tipo di carattere da usare tramite padWidth, invece del default 0.
Decisamente originale, invece, questa soluzione:

1
2
3
4
5
6
7
8
9
10
11
12
13
/**
 * string_pad
 *
 * @from        http://snipplr.com/view/700/stringpad/
 * @author      http://d.hatena.ne.jp/brazil/20060721/1153489937
 *
 * @param         str         - Striga da riempire
 * @param         len         - Numero totale di caratteri, comprensivo degli "zeri"
 * @param         ch          - Carattere usato per riempire
 */

function pad(str, len, ch){return new Array(len-(''+str).length+1).join(ch) + str}

alert(pad(56, 4, '0')); // 0056

Stesso risultato, con un approccio completamente diverso. Anche in questo caso abbiamo la possibilità di decidere il numero di caratteri padding tramite il parametro len e il tipo di carattere da usare tramite ch. Manca però l’uso del default previsto nella precedente funzione.
Quella che uso io, invece…:

1
2
3
4
5
6
7
8
9
10
11
12
/**
 * string_pad
 *
 * @author      Giovambattista Fazioli
 * @web         http://www.undolog.com
 *
 * @param         s           - Striga da riempire
 * @param         l           - Stringa che indica sia il carattere che la lunghezza
 *                              ad esempio "0000" = carattere "0" lunghezza 4
 */

function padding(s,l) { return( l.substr(0, (l.length-s.length) )+s ); }
alert( padding('123','0000') );

Se avete altre soluzioni interessanti non esitate a commentare :D

16 commenti a: “Varietà di coding e di coding”

  1. 14 ott, 2008 Napolux:

    Riga 12 della tua funzione immagino debba essere:

    alert( padding('123','0000') );
    
  2. 14 ott, 2008 Giovambattista Fazioli:

    @Napolux:

    Riga 12 della tua funzione immagino debba essere:alert( padding(’123′,’0000′) );

    Corretto!! :D

  3. 15 ott, 2008 Francesco Gavello:

    Interessanti, i 3 diversi approcci! :)

  4. 20 ott, 2008 Camelize, CamelCase | Undolog.com:

    [...] già visto nel post Varietà di coding e di coding gli approcci che uno sviluppatore può avere alla risoluzione di un problema sono diversi e [...]

  5. 06 nov, 2008 unwiredbrain:

    Ho testato i tempi di tutti e tre i metodi. Il primo prevedibilmente è il più lento, mentre il terzo è dannatamente veloce.

    Ho lanciato 100000 volte i singoli metodi in modo da fargli effettuare il padding a dieci cifre di un numero a quattro cifre, ed ho collezionato di volta in volta i tempi di esecuzione con un banale

    1
    2
    3
    4
    5
    6
    7
    8
    var timings = [];
    var time = 0;

    for (...) {
        time = (new Date).getTime();
        robaDaEseguire();
        timings[i] = ((new Date).getTime() - time);
    }

    Alla fine ho calcolato la media aritmetica dei singoli tempi.

    Il primo algoritmo impiega 0.06896 secondi, il secondo ne impiega 0.06896 mentre il terzo si spinge fino a 0.01331.

    Aumentando il numero di lanci ad un milione la differenza fra i tre comincia ad essere palpabile:
    il primo algoritmo impiega 0.047184 secondi, il secondo 0.028644 mentre il terzo appena 0.018635.

    La mia ricerca inutile per oggi è fatta. A presto, giovini.

    PS: tutto ciò ovviamente va preso con un sorriso sulle labbra… ;-)

  6. 06 nov, 2008 Napolux:

    @unwiredbrain:
    Per curiosità, su che browser hai effettuato i test? Hai provato altri browser per vedere se ci sono differenze tra browser e browser?

  7. 06 nov, 2008 Giovambattista Fazioli:

    @Napolux: bravo! Mi hai tolto le parole di bocca :D Mi ero incuriosito anch’io… sarebbe da provare con Google Chrome :D

  8. 06 nov, 2008 Napolux:

    PHP è sempre quello, JS cambia in base ai browser, no? :P

  9. 07 nov, 2008 Napolux:

    @Napolux:

    PHP è sempre quello, JS cambia in base ai browser, no?

    Mi sono spiegato male… Volevo dire “cambia il motore JS in base al browser”

  10. 07 nov, 2008 unwiredbrain:

    @Napolux, Giovambattista Fazioli: Firefox 3.0.3 su Linux.

    Opera ovviamente tira fuori risultati a dir poco esaltanti: nell’ordine 0.010882, 0.013681 e (udite udite) 0.007994 millisecondi! Praticamente il 77, il 52 ed il 57% in meno!

    Ah, mi accorgo solo ora che nel commento precedente parlavo di secondi: in realtà si tratta di millisecondi.

    Mi piacerebbe vedere come stanno le cose in casa KHTML/WebKit e Firefox 3.1, ma ancora non si dispone di robustezza e stabilità sufficienti per poter fare dei test seri. Vi prego di smentirmi nel caso sappiate qualcosa al riguardo, ne sarei felicissimo… :-)

    Per quanto riguarda Chrome, non appena sarà disponibile per Linux me lo spremerò per benino… ;-)

    Saluti.

    PS: presto pubblicherò i sorgenti della test suite, ora davvero non ho tempo…

  11. 07 nov, 2008 unwiredbrain:

    Ma soprattutto: perché mai il mio gravatar se n’è andato ad allegre donnine che fanno mercimonio di sé? Misteri di getAvatar…

  12. 07 nov, 2008 Giovambattista Fazioli:

    @Napolux:

    Mi sono spiegato male… Volevo dire “cambia il motore JS in base al browser”

    Corretto! Tuttavia, ad essere precisi, anche PHP non è proprio lo stesso; ci sono versioni diverse, su server diversi, con estensioni diverse. Ma questo è da considerare per casi assai più complicati del nostro. :D

  13. 10 nov, 2008 Napolux:

    @Giovambattista Fazioli:

    @Napolux:Mi sono spiegato male… Volevo dire “cambia il motore JS in base al browser”Corretto! Tuttavia, ad essere precisi, anche PHP non è proprio lo stesso; ci sono versioni diverse, su server diversi, con estensioni diverse. Ma questo è da considerare per casi assai più complicati del nostro.

    Fiscale… :P

  14. 10 nov, 2008 Giovambattista Fazioli:

    @Napolux: solo con te mi posso permettere di essere “preciso”… almeno hai capito cosa intendevo :D e apprezzi la fiscalità :D

  15. 10 nov, 2008 Napolux:

    Adesso comincio a trolleggiare qui, un po’ come hanno fatto da me per i KB / kB / Kb e compagnia bella.

    :mrgreen:

  16. 10 nov, 2008 unwiredbrain:

    @Napolux: Kib e KiB risolvono tutto.

Lascia un commento

TAG XHTML PERMESSI: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong> INSERIMENTO CODICE:
<pre></pre> // blocco generico
					<code></code> // blocco generico
					[cc_actionscript][/cc_actionscript] // Actionscript
					[cc_actionscript3][/cc_actionscript3] // Actionscript 3
					[cc_css][/cc_css] // CSS Style Sheet
					[cc_html][/cc_html] // HTML
					[cc_js][/cc_js] // Javascript
					[cc_objc][/cc_objc] // Objective-C
					[cc_php][/cc_objc] // PHP
					[cc_sql][/cc_sql] // SQL


Stop SOPA