JavaScript
unicode

Unicodeの丸数字(①とか)でやられた件

注意

記事の内容上、機種依存文字を使用しているため、
環境によっては文字が読みづらい状況となっていますがご了承くださいm(_ _)m

はじめに

みなさん、丸数字というもの使っていますか??
みたいに数字をまるで囲んであるやつです。ちなみにまで存在します。

そんなに進んで利用することも少ないと思いますが、
今回要件でリストの上から順番に丸数字を振ってほしいとリクエストが有りました。

「ただ連番降るだけっしょ!」と取り掛かったのですが、
考えていた実装と異なる内容になったのでよかったら参考にしてください。

実装

まずまでしかないです!ってことで、までで良いとお許しをもらえました。
とりあえず一安心:relaxed:

実装その①

のコードを取得して順に足していけば、それっぽくなるだろうという考えから
↓のようなコードを書きました(JavaScriptです)

function toCircled(num) {
  const base = '①'.charCodeAt(0);
  return String.fromCharCode(base + num - 1);
}
// 入力チェックは省略

それっぽい関数もできたのでいざ動作確認

for (let i = 1; i <= 50; i++) {
  console.log(toCircled(i));
}

// ①
// ②
// ③
// ...   いい調子!
// ⑲
// ⑳
// ⑴    !?
// ⑵    !!??

から先で違うパターンの数字が出てきたー:scream:
から別の場所にあるのか...

コード値を調べてみる

'①'.charCodeAt(0); // -> 9312
'⑳'.charCodeAt(0); // -> 9331
'㉑'.charCodeAt(0); // -> 12881

だいぶ飛んでる。
20で条件分岐するようにします!

実装その②

21以上の場合はを基準にするように変更しました。

function toCircled(num) {
  if (num <= 20) {
    const base = '①'.charCodeAt(0);
    return String.fromCharCode(base + num - 1);
  }
  const base = '㉑'.charCodeAt(0);
  return String.fromCharCode(base + num - 21);
}

いざ動作確認

for (let i = 1; i <= 50; i++) {
  console.log(toCircled(i));
}

// ①
// ...
// ⑳
// ㉑    よっしゃ!!
// ㉒
// ...
// ㉞
// ㉟
// ㉠    !?
// ㉡    !!??

36にまた見えない壁があったのか...
ここでようやくGoogle先生にご相談 
Wikipadiaにまさに丸数字のページが!!!

最初に20で躓いたときに見るべきでした:weary:

実装その③ (最終版)

function toCircled(num) {
  if (num <= 20) {
    const base = '①'.charCodeAt(0);
    return String.fromCharCode(base + num - 1);
  }
  if (num <= 35) {
    const base = '㉑'.charCodeAt(0);
    return String.fromCharCode(base + num - 21);
  }
  const base = '㊱'.charCodeAt(0);
  return String.fromCharCode(base + num - 36);
}

これで動くはず...っ!!

for (let i = 1; i <= 50; i++) {
  console.log(toCircled(i));
}

// ①
// ...
// ㉟
// ㊱    やったー!
// ㊲
// ...
// ㊿

あとがき

2,3行で終わると思っていたので、ここまで大きくなるとは思っていませんでした。
そして最初につまずいた段階で「他にもあるのでは...?」という疑問を持てなかったことが今回の敗因です。

もし何かの参考になればと思います( ˘꒳˘ )

おしまい