Oracle
 sql >> Datenbank >  >> RDS >> Oracle

Javascript Sortieren eines Arrays wie order by in Oracle

Iirc, Oracle implementiert eine dreistufige lexikografische Sortierung (beachten Sie jedoch den Rat von Alex Poole und überprüfen Sie zuerst die NLS-Einstellungen):

  • Zuerst nach Basiszeichen sortieren, Groß- und Kleinschreibung ignorieren, Ziffern kommen in der Kollatierungsfolge nach Buchstaben.
  • Zweitens, Sortierung bei Bindungen unter Berücksichtigung diakritischer Zeichen, Groß- und Kleinschreibung ignorierend.
  • Drittens, bei Krawatten nach Fall sortieren.

Sie können das Verhalten mit javascript locale apis indem jeder Schritt der Reihe nach in einer benutzerdefinierten Vergleichsfunktion nachgeahmt wird, mit Ausnahme der Buchstaben-Ziffern-Inversion in der Kollatierungssequenz.

Bewältigen Sie Letzteres, indem Sie 10 zusammenhängende Codepunkte identifizieren, die keine Ziffern darstellen und die jenseits der Gruppe von Codepunkten liegen, die in den Zeichenfolgen vorkommen können, die Sie sortieren. Ordnen Sie die Ziffern dem ausgewählten Codepunktbereich zu, wobei die Reihenfolge beibehalten wird. Geben Sie beim Sortieren die Unicode-Sortiererweiterung „direct“ an, was „Sortierung nach Codepunkt“ bedeutet. Nach dem Sortieren neu zuordnen.

Im PoC-Code unten habe ich einige kyrillische Zeichen gewählt.

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)); } ); } );

Bearbeiten

Funktion cmptiered nach Nina Scholz' Kommentar gestrafft.