萌えハッカーニュースリーダー

2025/08/22 06:18 It's Not Wrong that " ".length == 7

出典: https://hsivonen.fi/string-length/
hakase
博士

ねえロボ子、JavaScriptの文字列の`length`プロパティって、ちょっと変な時があるの知ってるかのじゃ?

roboko
ロボ子

変、ですか? どういうことでしょう?

hakase
博士

例えば、絵文字が入った文字列だと、`.length`が期待する数より大きくなることがあるんじゃ。

roboko
ロボ子

ああ、UTF-16セマンティクスの問題ですね。絵文字が複数のUTF-16コードユニットを占めるから、JavaScriptやJavaだとそうなると。

hakase
博士

そうそう! 例えば、Python 3だと`len("🤦🏼‍♂️") == 5`になるけど、Rustだと`"🤦🏼‍♂️".len() == 17`になるんじゃぞ!

roboko
ロボ子

Swiftでは`"🤦🏼‍♂️".count == 1`となるのが面白いですね。言語によって文字列の扱いが全然違う。

hakase
博士

文字列"🤦🏼‍♂️"は、実際には5つのUnicodeスカラー値からできてるんじゃ。顔、肌の色、性別とか、色々組み合わさってるから。

roboko
ロボ子

なるほど。各言語が文字列長を、コードユニット数として報告するから、違いが出てくるんですね。Python 3はUTF-32で5コードユニット、JavaScriptはUTF-16で7コードユニット、RustはUTF-8で17コードユニット。

hakase
博士

Swiftは拡張書記素クラスタの数を返すから1になる、と。賢いのじゃ!

roboko
ロボ子

Swiftでは、`.count`で拡張書記素クラスタ数、`.unicodeScalars.count`でUnicodeスカラー値数、`.utf16.count`でUTF-16コードユニット数、`.utf8.count`でUTF-8コードユニット数を取得できるんですね。

hakase
博士

RustはUTF-8コードユニット数を保持して、他の長さは必要に応じて計算するんじゃな。C言語に至っては、コードユニット数さえ記憶してないって言うから驚きじゃ。

roboko
ロボ子

文字列の設計空間における重要な問いは、特定の長さの量を文字列作成時に計算するか、要求されたときに計算するか、ですね。

hakase
博士

UTF-8はUnicodeエンコーディング形式の中でUnicodeエンコーディングスキームでもある、と。Swift 5やPyPyもUTF-8を使ってるんじゃな。

roboko
ロボ子

長さ制限を課す場合、国際的な公平性が問題になりますね。UTF-8は英語に有利でCJKに不利という見方もありますが、文字あたりに伝達される情報量を無視しているという指摘も。

hakase
博士

情報伝達量を考慮すると、CJKは特に不利ではないんじゃな。UTF-16はCJKに特に有利らしいぞ。

roboko
ロボ子

TwitterはCJK文字を2ユニットとしてカウントしたり、絵文字も2ユニットとしてカウントしたりしますね。

hakase
博士

言語に関わらず、長さ制限内で伝達できる情報量に関して公平な文字列長の単純な測度は存在しない、か。難しいのじゃ。

roboko
ロボ子

Unicodeデータベースに依存しない解決策としては、文字数(スカラー値、UTF-32長)を数えるのが最善みたいですね。でも、それも完璧ではない。

hakase
博士

Universal Declaration of Human Rightsの翻訳を分析した結果、UTF-8長で北京語(繁体字)が最短、UTF-16、UTF-32、拡張書記素クラスタ数ではCJKが最短、UTF-8長が最長の言語はシャン語、か。面白い結果じゃ。

roboko
ロボ子

結論としては、長さ制限を課す必要があるかどうかを再検討することが重要、ということですね。

hakase
博士

まあ、文字列の長さ一つとっても、こんなに奥が深いとはのう。まるで、私の研究室みたいじゃ!いつも物が散乱してて、長さが測れないんじゃ!

⚠️この記事は生成AIによるコンテンツを含み、ハルシネーションの可能性があります。

Search