Oracle
 sql >> Database >  >> RDS >> Oracle

Javascript Ordinamento di un array simile all'ordine in Oracle

Iirc, Oracle implementa un ordinamento lessicografico a 3 livelli (ma ascolta il consiglio di Alex Poole e controlla prima le impostazioni NLS):

  • Prima ordina in base ai caratteri di base ignorando maiuscole e minuscole e segni diacritici, le cifre vengono dopo le lettere nella sequenza di confronto.
  • In secondo luogo, sui legami ordina rispettando i segni diacritici, ignorando le maiuscole.
  • Terzo, sui pareggi ordina per caso.

Puoi emulare il comportamento utilizzando javascript locale apis imitando ogni passaggio a turno in una funzione di confronto personalizzata, ad eccezione dell'inversione lettera-cifra nella sequenza di confronto.

Affronta quest'ultimo identificando 10 punti di codice contigui che non rappresentano cifre e che si trovano oltre l'insieme di punti di codice che possono verificarsi nelle stringhe che stai ordinando. Mappa le cifre sull'ordine di conservazione dell'intervallo di punti di codice scelto. Quando esegui l'ordinamento, specifica l'estensione di confronto Unicode "diretta" che significa "ordinamento per punto di codice". Rimappa dopo l'ordinamento.

Nel codice PoC qui sotto ho scelto alcuni caratteri cirillici.

function cmptiered(a,b) {
    //
    // aka oracle sort
    //
    return lc_base.compare(a, b) || lc_accent.compare(a, b) || lc_case.compare(a, b);
}  // cmptiered

var lc_accent   = new Intl.Collator('de', { sensitivity: 'accent' });
var lc_base     = new Intl.Collator('de-DE-u-co-direct', { sensitivity: 'base' });
var lc_case     = new Intl.Collator('de', { caseFirst: 'lower', sensitivity: 'variant' });

var array = ['Ba12nes','Apfel','Banane','banane','abc','ABC','123','2', null, 'ba998ne' ];

// Map onto substitute code blocks
array = array.map ( function ( item ) { return (item === null) ? null : item.replace ( /[0-9]/g, function (c) { return String.fromCharCode(c.charCodeAt(0) - "0".charCodeAt(0) + "\u0430".charCodeAt(0)); } ); } );

array.sort(cmptiered);

// Remap substitute code point
array = array.map ( function ( item ) { return (item === null) ? null : item.replace ( /[\u0430-\u0439]/g, function (c) { return String.fromCharCode(c.charCodeAt(0) - "\u0430".charCodeAt(0) + "0".charCodeAt(0)); } ); } );

Modifica

Funzione cmptiered semplificato in seguito al commento di Nina Scholz.