多くの人は基本的に > または < 比較で文字列を比較します。
localeCompare を使用する人もいますが、本当にこのプロトタイプ メソッドを使用しますか?
以下は、文字列内の数値を比較する方法を示す例です。
// 当我们比较 '10' 和 '9' 的时候,返回值小于0
'10'.localeCompare('9') // -1
したがって、この状況に遭遇した場合、実際には、 localeCompare メソッドは比較するための多くのパラメーターも提供します。
// locale 参数
'10'.localeCompare('9', 'zh-u-kn-true') // 1
'a'.localeCompare('A', 'zh-u-kf-upper') // 1
'a'.localeCompare('A', 'zh-u-kf-lower') // -1
// locale u 后边可以添加多种参数,比如 zh-u-kf-lower-kn-true
// options 参数
'10'.localeCompare('9', 'zh', { numeric: true }) // 1
'a'.localeCompare('A', 'zh', { caseFirst: 'upper' }) //1
'a'.localeCompare('A', 'zh', { caseFirst: 'lower' }) // -1
kn
「1」 < 「2」 < 「10」などの数値順序を使用するかどうかを指定します。可能な値は "true"
次のとおり です。"false"
kf
大文字を最初にソートするか、小文字を最初にソートするかを指定します。可能な値は "upper"
、、、、 "lower"
または です。"false"
特定の戻り値 -1 または 1 に依存しないでください。W3C 仕様では戻り値が正と負であることのみを要求しており、特定の値は指定していないため、返される正の数値と負の数値の値はブラウザーごとに (およびブラウザーのバージョンごとに) 異なります。ブラウザによっては、-2 や 2、あるいはその他の負の値、正の値を返す場合があります。
したがって、判断するときは、0 より大きいか、0 より小さいか、0 に等しいかに基づいて判断する必要があります。
locales
引数は、 BCP 47 言語タグの文字列、または複数の言語タグを含む配列である必要があります。locales
パラメーターが指定されていないか未定義の場合は 、実行時のデフォルトのロケールが使用されます。
BCP 47 言語タグは言語または地域を表します (この 2 つに大きな違いはありません)。最も一般的な形式では、言語コード、文字コード、国コードがこの順序で含まれ、すべてハイフンで区切られます。例えば:
"hi"
: ヒンディー語 (第一言語)。"de-AT"
:在奥地利使用的德语 (primary language with country code)。
"zh-Hans-CN"
: 中国で使用される簡体字中国語 (文字と国コードを含む主言語)。
「u」はユニコードを表します。これを使用して、カスタム ロケール固有の動作を持つ Collat or 、NumberFormat、または DateTimeFormat オブジェクトをリクエストできます。例えば:
"de-DE-u-co-phonebk"
: ドイツ語の電話帳のソート バリアントを使用します。これは、ウムラウトを文字ペア (ä → ae、ö → oe、ü → ue) に展開します。"th-TH-u-nu-thai"
: タイ語の数値表現を数値形式で使用します (๐、๑、๒、๓、๔、๕、๖、๗、๘、๙)"ja-JP-u-ca-japanese":在日期和时间格式化中使用日本的日历表示方式,所以 2013 会表示为平成 25
3 番目のパラメーター オプションの使用に慣れている場合は、未定義のロケール パラメーターを渡してシステムのデフォルトを使用できます。
options
次のプロパティの一部またはすべてをサポートするオブジェクトです
localeMatcher |
地理的マッチングアルゴリズムの使用。可能な値は |
usage |
比較の対象がソートか検索かを指定します。可能な値は "sort" と で "search" 、デフォルトは です "sort" 。 |
sensitivity |
ソート手順の感度を指定します (文字列の違いがゼロ以外の結果値をもたらす必要がある)。可能性のあるものは次のとおりです。
|
ignorePunctuation |
句読点を無視するかどうかを指定します。可能な値は true と で false 、デフォルトは です false 。 |
numeric |
「1」<「2」<「10」のように数値ソートを指定するかどうか。可能な値は true と で false 、デフォルトは です false 。options このオプションは、プロパティまたは Unicode 拡張機能を介して設定できます。両方が設定されている場合は、 が options 優先されます。このプロパティをサポートするために実装は必要ありません。 |
caseFirst |
大文字と小文字を区別した並べ替えを指定します。可能な値は "upper" 、 、"lower" または "false" (ロケールのデフォルトを使用)、デフォルトは です 。このオプションは 、プロパティまたは Unicode 拡張機能を介して設定"false" できます 。options 両方が設定されている場合は、 が options 優先されます。このプロパティをサポートするために実装は必要ありません。 |
これを知っていると、パッチワークが多いデータに対して分割と並べ替えを使用できます。
const a = 'abc12嘻嘻3AB哈哈C456abcABC789'
a.split(/([a-z]+|[0-9]+|[A-Z]+)/).filter(item => !!item)
// ['abc', '12', '嘻嘻', '3', 'AB', '哈哈', 'C', '456', 'abc', 'ABC', '789']
// 分割之后就可以根据不同的值进行排序
const arr = ["a-10-张三", "钱5", "A-9-赵5", '孙八', "a-10","a-9-李四", "A-10", "钱六", "A-10-张三", "a-10-李四", "A-10-李四"];
const toSeparate = (str) => {
if (typeof str !== 'string') return
const regex = /([a-z]+|[0-9]+|[A-Z]+)/
return str.split(regex).filter(item => !!item)
}
// 个人觉得,不是同一个类型,比较就应该用默认,不用纠结根据类型获取不同比较
// 如果想分得更细,就自己加内容
const compare = new Intl.Collator('zh-u-kn-true-kf-lower').compare // 小写字母放在大写字母前面
arr.sort((one, other) => {
const oneSeparate = toSeparate(one)
const otherSeparate = toSeparate(other)
while (oneSeparate.length && otherSeparate.length) {
if (compare(oneSeparate[0], otherSeparate[0]) === 0) {
oneSeparate.shift()
otherSeparate.shift()
} else {
return compare(oneSeparate[0], otherSeparate[0])
}
}
// 到这一步说明 某一个 已经没有值了
if (oneSeparate[0] === otherSeparate[0]) return 0
return oneSeparate[0] ? 1 : -1 // 表示有值的放在后边,没有值了的放在前面
});
console.log(arr);
// ['钱5', '钱六', '孙八', 'a-9-李四', 'a-10', 'a-10-李四', 'a-10-张三', 'A-9-赵5', 'A-10', 'A-10-李四', 'A-10-张三']