LoginSignup
12
7

More than 5 years have passed since last update.

macOSの濁点問題について

Last updated at Posted at 2018-01-01

現象

Node.jsで取得したフォルダ名と文字列リテラルが同じ文字(っぽい)のに一致しない。
ただし濁点付きの文字に限る。

  • 確認した環境
    • macOS Sierra v10.12.6
    • node v8.2.1

再現手順

こんな感じでフォルダがあったとする。

$ ll /data
total 0
-rw-r--r--  1 mimizq  staff  0  1  2 00:06 せ
-rw-r--r--  1 mimizq  staff  0  1  2 00:06 ぜ

フォルダ一覧を取得する。

const fs = require('fs');
const chars = fs.readdirSync('/data');
// [せ, ぜ]

濁点付きの文字だけ一致しない。

let countA = 0;
let countB = 0;

for(let c of chars) {
  if(c === '') countA++;
  if(c === '') countB++;
}

console.log(countA); // 1
console.log(countB); // 0

なぜ一致しないのか

文字コードが違うから。

for(let c of chars) {
  console.log(c.charCodeAt(0));
}
// 12379
// 12379

// フォルダ名の「ぜ」は、 12379, 12441 となっており、濁点入りで実質2文字扱い。
// 一方、リテラルの「ぜ」は、12380 で1文字扱い。なので当然一致しない。

理由

macOSのファイルシステムの問題らしい。
こちらの方が詳しく書いてくださっているのでリンクしておきます。
https://qiita.com/knaka/items/48e1799b56d520af6a09

結論

こうすればいい。

const chars = fs.readdirSync('/data')
  .map(c => {
    return c.normalize('NFC'); // NFCで正規化
  });

let countA = 0;
let countB = 0;

for(let c of chars) {
  if(c === '') countA++;
  if(c === '') countB++;
}

console.log(countA); // 1
console.log(countB); // 1 <- 一致した

for(let c of chars) {
  console.log(c.charCodeAt(0));
}
// 12379
// 12380 <- 1文字扱いされている

だからテキストエディタでソートしたときの挙動が意図していたものと違ったのかと納得。
macを使い始めて数ヶ月経ちますが、操作はそこそこ慣れてもOSの仕様的なところは全然知らないので結構困ります。

総合的な開発効率は正直Windowsのほうが上だったような。
最近のWindowsはWSLでBash使えるし。
慣れの問題でしょうか。

英語環境だとmac良いのかもしれないけど日本語環境だとちょっと使いづらいかも。
小洒落たポスターとかスライド作るにはいいんだけど。

12
7
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
12
7