DEV Community

Cover image for Ordinare la numerazione di un documento o lista espressa a livelli: 1.0, 1.1.2, 2.0,5.2.7
Paolo Carraro
Paolo Carraro

Posted on

Ordinare la numerazione di un documento o lista espressa a livelli: 1.0, 1.1.2, 2.0,5.2.7

Cosa ho imparato oggi? per ordinare delle stringhe che rappresentano la numerazione di un documento non possiamo ricorrere all'ordinamento alfanumerico.
Tipicamente un documento è ordinato usando un metodo per punti:
2.1.3

Quando vediamo questa numerazione traduciamo questi numeri cardinali in ordinali: di fatto leggiamo qualcosa come per esempio
terzo paragrafo del primo sottotitolo del secondo capitolo.
In più potremmo dover considerare che abbiamo casi del tipo
2.2
quindi mancanti della terza componente della numerazione in quanto questa si presuppone 0.

Normalizzare le parti che compongono la numerazione

La soluzione che ho trovato cercando risorse in internet è quella di normalizzare prima di tutto il numero di parti in modo che ne abbiamo sempre lo stesso numero da valutare.
Quindi passare da

1.3.5 2.1 5.3.5.6 10 
Enter fullscreen mode Exit fullscreen mode

a

1.3.5.0 5.3.5.6 2.1.0.0 10.0.0.0 
Enter fullscreen mode Exit fullscreen mode

Rendere ininfluente la posizione del numero aumentando il valore che lo esprime

Per evitare che 10 risulti minore di 2, come è per l'ordinamento alfanumerico, il trucco è quello di aumentare le cifre che compongono la numerazione sommando un numero più alto della cifra che ci aspettiamo essere il massimo. Per esempio sommando sempre 100 ad ogni parte otteniamo:

101.103.105.100 105.103.105.106 102.101.100.100 110.100.100.100 
Enter fullscreen mode Exit fullscreen mode

Quello che abbiamo, nonostante siano espressi da numeri, lo andremo a valutare come stringa in quanto semplifica di molto la comparazione e inoltre permette anche di gestire numerazioni contenenti lettere. Per esempio potremmo avere

7.1.b 7.2 
Enter fullscreen mode Exit fullscreen mode

che diventa

107.101.10b.100 107.102.100.100 
Enter fullscreen mode Exit fullscreen mode

Il codice per implementare questo algoritmo l'ho scritto così

// considerando che si possa arrivare ad una numerazione di centinaia const templatePart = '1000'; // numerazione composta da 6 livelli di annidamento const template = [templatePart, templatePart, templatePart, templatePart, templatePart, templatePart]; const convertForComparing = (parNumeration: string) => { // "somma" del numero template let parts = parNumeration.split('.').map( (p) => templatePart.substring(0, templatePart.length - p.length) + p); // normalizzazione del numero di parti parts = [...parts, ...template.slice(parts.length)]; return parts.join('.'); }; const sortByParagraphNumeration = (a: Item, b: Item) => { const pa = convertForComparing(a.par.toLowerCase() || ''); const pb = convertForComparing(b.par.toLowerCase() || ''); if (pa < pb) { return -1; } if (pa > pb) { return 1; } return 0; }; 
Enter fullscreen mode Exit fullscreen mode

La spiegazione di sicuro è manchevole di formalismo e fin troppo empirica ma nel mio caso pare funzionare a dovere.
E voi come avreste risolto?

Top comments (0)