Iirc、Oracleは3層の辞書式ソートを実装しています(ただし、Alex Pooleのアドバイスに注意し、最初にNLS設定を確認してください):
- 最初に大文字と小文字と発音区別符号を無視して基本文字で並べ替えます。数字は照合シーケンスの文字の後に続きます。
- 第2に、タイでは発音区別符号を尊重し、大文字と小文字を区別しません。
- 第3に、同点の場合はケース別に並べ替えます。
javascriptロケールAPIを使用して動作をエミュレートできます。 a> 照合シーケンスの文字と数字の反転を除いて、カスタム比較関数で各ステップを順番に模倣します。
数字を表さず、並べ替える文字列で発生する可能性のあるコードポイントのセットを超えている、10個の連続するコードポイントを特定することにより、後者に取り組みます。選択したコードポイント範囲の保存順序に数字をマップします。並べ替えるときは、Unicode照合拡張機能「direct」を指定します。これは「コードポイントによる並べ替え」を意味します。並べ替え後に再マップします。
以下のPoCコードでは、キリル文字をいくつか選択しました。
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)); } ); } );
編集
関数cmptiered
NinaScholzのコメントに従って合理化されました。