Share |

sabato 1 gennaio 2011

Javascript: Decorare valori numerici


Questo articolo ed il codice sorgente in esso contenuto è da considerarsi obsoleto e superato. Seppur tutto ciò a cui qui si fa riferimento sia tutt'ora reperibile ed utilizzabile, è consigliata la lettura e l'utilizzo della classe javascript Number.

Grazie, MA

Il primo articolo Javascript postato nel 2011 tratta della classe MA_Numbers: un componente che offre la possibilità di decorare numeri e di normalizzare stringhe di numeri, precedentemente decorati, per ri-ottenere i valori numerici originali in maniera rapida e comoda.

Tutto il codice sorgente dell'articolo è scaricabile a questo indirizzo.

La classe MA_Numbers

Grazie alla classe javascript MA_Numbers risulterà facile poter introdurre nelle proprie applicazioni la presentazione di valori numerici decorati, o formattati, con separatori di migliaia e decimali; e nel caso quei valori dovessero essere riutilizzati per eseguire calcoli matematici, la classe è in grado di eseguire una normalizzazione del dato per ottenere il valore numerico originale rimuovendone la decorazione.

In ambito Java questo componente sarebbe definito decorator, proprio perchè in grado di trasformare il numero puro, quindi con il punto separatore di decimali, in una stringa nella quale vi sono punti per separare le migliaia e la virgola per i decimali: si potrebbe dire che trasforma il dato da un formato utile alla macchina ad un altro molto più comprensibile per gli umani.

Questa classe non va istanziata ma è da utilizzarsi in modalità statica, questo non va a pesare sulle risorse a disposizione del browser, e necessita della libreria javascript jQuery.

Il componente espone anche un comodo metodo per eseguire arrotondamenti di numeri decimali, cosa che attualmente la classe javascript Math non possiede e di cui si è discusso in un precedente post raggiungibile a questo indirizzo.

La classe è a disposizione di chiunque e quindi tutti possono copiarla, utilizzarla e modificarla a proprio piacimento.

E' comunque gradito un feedback o commento in caso di utilizzo della stessa.

/**
 * Class MA_Numbers.
 *
 * This is a utility class to decorate numbers
 * and normalize decorated numbers to their originals.
 * It comes with some other useful methods like the roundTo() function.
 * 
 * Note:
 * This class is free: you can copy, change and use it.
 * Use it in static mode, don't istanziate.
 *
 * Warnings:
 * This class needs jQuery library.
 *
 * @author  Mirko Agrati - mirko(dot)agrati(at)gmail(dot)com
 * @version 1.0
 */
function MA_Numbers(){}

/** ------------ Static properties --------------- */
MA_Numbers.DECIMALS_TOKEN = ',';
MA_Numbers.THOUSANDS_TOKEN = '.';

/** ------------ Static methods --------------- */

/**
 * Normalizza la stringa passata come parametro e
 * restituisce il numero corrispondente.
 *
 * ES: 1.234.567,89 -> 1234567.89
 *
 * @param    str  Il dato stringa formattato da normalizzare.
 * @returns       Un numero di tipo float.
 */
MA_Numbers.normalizeNumbers = function (str){
  if(str == NaN || $.trim(str) == '-' || $.trim(str) == ''){
    return '0';
  }
  var t = str;
  var global = str.split(MA_Numbers.DECIMALS_TOKEN); 
 
  if(global.length >= 1){
    var t = global[0];
    while(t.index0f(MA_Numbers.THOUSANDS_TOKEN) > -1)
      t = t.replace(MA_Numbers.THOUSANDS_TOKEN,'');
    
    if(global.length > 1)
      t += MA_Numbers.THOUSANDS_TOKEN + global[1];
  }
  return parseFloat(t);
}


/**
 * Formatta e decora un numero in una stringa di testo con separatori
 * di migliaia e di decimali.
 *
 * ES: 1234567.89 -> 1.234.567,89
 *
 * @param    val  Il numero da decorare.
 * @returns       Una stringa.
 */
MA_Numbers.decorateNumbers = function (val){
  if(val == NaN || val == null || $.trim(val) == '' || $.trim(val) == '0')
    return '0';
  
  val = ''+val;
  var nparts = val.split(MA_Numbers.THOUSANDS_TOKEN);  
  val = nparts[0];
    
  var result = "";
  
  //Estraggo la parte intera con l'eventuale segno negativo.
  var intVal = parseInt(val)+'';
  var segno = "";
  if(intVal < 0){
    segno = "-";
    intVal = (-1 * intVal) + '';
  }
 
  //Giro la stringa e la converto in array.
  //E' più comodo lavorare a partire dal termine della stringa.
  var c = 0;
  var arr = new Array();
  for(var x=(intVal.length - 1); x>=0; x--){
    arr[c] = intVal.charAt(x);
    c++;
  }
 
  //decoro le migliaia.
  var arrT = new Array();
  for(var i = 0; i<arr.length; i++){
    var s = arr[i];  
    if(i%3 == 0 && i != 0)
      s += MA_Numbers.THOUSANDS_TOKEN;
   
    arrT[i] = s;
  }

  //Ri-giro l'array e creo la stringa con la parte intera
  //correttamente formattata.
  result = arrT . reverse() . join('');  
    
  //Se presente aggiungo la parte decimale
  if(nparts.length > 1)
    result += MA_Numbers.DECIMALS_TOKEN + nparts[1];
      
  return segno + result;
}

/**
 * Utile per gli arrotondamenti di valori decimali.
 *
 * @param    value     Il numero, o stringa, da arrotondare.
 * @param    decimals  Numero di decimali da restituire.
 * @returns            Un numero arrotondato a decimals
 *                     decimali.
 */
MA_Numbers.roundTo = function (value, decimals){
  var i = parseFloat(value) * Math.pow(10, parseInt(decimals));
  i = Math.round(i);
  return i / Math.pow(10, decimals);
}

La classe è ben commentata, soprattutto nei punti più critici, e, a parte l'uso avanzato ed intensivo degli array, direi che non c'è molto da aggiungere.

Mostrerò ora come poterla utilizzare attraverso uno script javascript.

Utilizzare la classe MA_Numbers

In questo semplice esempio sarà mostrato quanto è semplice introdurre ed utilizzare il componente all'interno di una applicazione javascript.

L'esempio consiste nel decorare, normalizzare, arrotondare e ri-decorare un numero.

<html lang="en">
<head>
  <title>Formattare, parsare numeri</title>
  <script type="text/javascript" src="./js/jquery-1.4.3.min.js"></script>
  <script type="text/javascript" src="./js/class.MA_Numbers.js"></script>
  <script type="text/javascript">
window.onload = function(){
  var n = 12345.6789
  var out = "Numero originale: <b>" + n + "</b><br>";
    
  var s = MA_Numbers.decorateNumbers(n)
  out += "Numero decorato: <b>" + s + "</b><br>";
    
  s = MA_Numbers.normalizeNumbers(s)
  out += "Numero originale ricavato normalizzando il dato decorato: <b>" 
          + s + "</b><br>";
    
  var dec = 3
  s = MA_Numbers.roundTo(s,dec)
  out += "Numero arrotondato a <b>" + dec + "</b> decimali : <b>" 
          + s + "</b><br>";
    
  s = MA_Numbers.decorateNumbers(s)
  out += "Numero arrotondato decorato: <b>" + s + "</b><br>";
    
  document.getElementsByTagName('body')[0].innerHTML = out;
}
  </script>
</head>
<body></body>
</html>

L'esempio produce nel corpo della pagina il seguente output:

Numero originale: 12345.6789
Numero decorato: 12.345,6789
Numero originale ricavato normalizzando il dato decorato: 12345.6789
Numero arrotondato a 3 decimali : 12345.679
Numero arrotondato decorato: 12.345,679

Utilizzare la classe MA_Numbers, come è possibile notare dall'esempio di sui sopra, è effettivamente semplice e la sua introduzione all'interno di un'applicazione già esistente risulta essere rapido ed indolore.

Approfitto dell'occasione per porgere a tutti i miei auguri per un 2011 ricco di successi e soddisfazioni.

Alla prossima,
MA.

1 commenti:

  1. E' in cantiere la creazione di una classe di model per la rappresentazione di numeri, che consenta l'esecuzione di operazioni matematiche con la sintassi OOP.

    La classe incapsulerà i metodi della libreria javascript Math e ne fornirà di nuovi, tra i quali la possibilità di decorare il proprio valore:)

    A presto.
    MA

    RispondiElimina

Non ti è chiaro qualcosa?
No problem, posta il tuo dubbio ;)

..... e ricordati di firmarlo!