Javascriptの ‘文字列’.length の罠

Javascriptから少し離れると忘れてしまう問題。
最近、立て続けで見かけたので備忘録として書きます。

先に結論だけ書くと、現状では完全な解決は難しいということです。

lengthについて

MDNによる length について書かれたページです。
こちらの内容をほぼなぞったものになります。

String length – JavaScript | MDN
https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Global_Objects/String/length

Javscript で文字列の長さを取得したいときはまず length を使うことを考えるでしょう。

const mojiretsu1 = 'mojiretsuhadoushutokusuruka';
console.log(mojiretsu1.length);
// 27
取得できました。
文字列を日本語に置き換えても問題なく取得できます。
const mojiretsu2 = '文字列はどう取得するか';
console.log(mojiretsu2.length);
// 11

何も問題はないように見えます。

全てはうまくいっています。

要素は言葉を切り分ける

MDNにある説明を引用します。

String length – JavaScript | MDN

細かい説明はMDNを見ていただくとして、ここで重要なのは length が文字の数ではなくコードユニットの数で表されることです。

以下に例を示します。

const emoji = '🏴󠁧󠁢󠁥󠁮󠁧󠁿';
console.log(emoji.length);
// 14

なんだかよく分からないこの謎の旗 🏴󠁧󠁢󠁥󠁮󠁧󠁿 の length は14ものコードユニットを内包します。
多すぎる、修正が必要でしょう・・・。

これを見てあなたはすぐに「絵文字禁止にしよう」と思うかもしれません。
しかし、それはベストな解決方法ではないことにすぐに気付くでしょう。

const umaiYasuiHayai = '𠮷野家';
console.log(umaiYasuiHayai.length);
// 4

𠮷野家.length は4。
𠮷の length は2となっているため、このような結果となります。

length はどう生きるか

MDNにある対応例を引用します。

function getCharacterLength (str) {
    return [...str].length;
}
console.log(getCharacterLength('🏴󠁧󠁢󠁥󠁮󠁧󠁿'));
// 7
console.log(getCharacterLength('𠮷野家'));
// 3

これにより ‘𠮷野家’ に対しては3を得ることが可能になります。
しかし、謎の旗は7となってしまい、依然、正しい文字数を得ることができません。

見ての通り、この方法は完璧ではありませんが、いまのところ、これはいくらかマシな方法といえます。
厳しい現実ですが、私たちは常に前を見据える必要があるでしょう。

未来へ

将来の話になりますが、Intl.Segmenter という新しい仕様によりこの問題は解決される見込みです。内容は省きますが、これを書いている現在では一部の環境でしか対応していません。Polyfill は存在するようですので、導入可能な環境であればそちらを利用できるでしょう。

また、length の話からは逸れますが、’文字列’.split() 等でも同様の問題を抱えています。厄介な問題ではあるのですが、Javascript を常に触っていることでもない限り忘却しがちなところも輪にかけて厄介な点です。その度に ‘文字列’.length には期待して、がっかりさせられ、また忘れて期待してしまうのです。

噫無情。

というほどでもないですが、なるべく早く解決されることを期待したいところです。


Demucs で音源分離

音源分離という技術分野があります。
音楽データを入力として、各楽器や音声毎に分離して出力するというものです。
例えば曲の中から歌の部分だけを分離して消してしまえばカラオケのデータになります。
音源分離は昔から様々な手法で取り組まれてきましたが、近年ではこの分野でもAI技術が応用されています。

オープンソースの音声分離ソフトウェアの一つに「Demucs」があります。
Metaの研究所が開発しているもので、GitHub で公開されています。
Python が動く環境であれば簡単にインストールできるようなので使ってみました。

https://github.com/facebookresearch/demucs/blob/main/docs/linux.md
に従ってインストールします。
まずはpythonのバージョンを確認。

$ python3 --version
Python 3.9.2

Python 3.8以上であれば大丈夫です。

pip でインストール

$ pip3 install --user -U demucs

これだけです。
実行します。

$ python3 -m demucs --mp3 -d cpu music.mp3

Core i5 8400 のマシンで2分10秒ほど。
結果ファイルは以下のようなディレクトリ構造に置かれます。

$ find separated
separated
separated/htdemucs
separated/htdemucs/music
separated/htdemucs/music/bass.mp3
separated/htdemucs/music/vocals.mp3
separated/htdemucs/music/drums.mp3
separated/htdemucs/music/other.mp3

ボーカル、ベース、ドラム、それ以外といったところですね。
mp3 オプション無しで実行すれば、結果は wav ファイルになります。

ボーカルとそれ以外、みたいな分離もできます。

$ python3 -m demucs --two-stems=vocals --mp3 music.mp3
$ ls separated/htdemucs/music
no_vocals.mp3  vocals.mp3

実際に聴いてみると、綺麗にそれぞれのパートに分かれています。変なノイズが乗っていたり、別のパートが混ざっていたりということもほぼありません。
ボーカルだけのファイルを聴くのはなかなか不思議な気分です。


「RubyWorld Conference 2023」に協賛させていただきます

「RubyWorld Conference 2023」に、Goldスポンサーとして協賛させていただきます。

<期間>
2023年11月9日(木)、10日(金)
<会場>
島根県立産業交流会館「くにびきメッセ」
<主催>
RubyWorld Conference開催実行委員会
https://2023.rubyworld-conf.org/ja/


【Figma】Config2023で気になった機能を紹介

6月22日にFigmaのイベント「#Config2023」で新機能が発表されました。

便利でワクワクする機能が多く発表されたので、その中でも個人的に気になった機能を紹介しようと思います。

相変わらず紹介動画もおしゃれ。

開発者モードの追加

コーディングやアプリ開発する際に、Figmaからスムーズに作業を移行できる「開発者モード」が追加されました。
https://www.figma.com/ja/blog/introducing-dev-mode/

個人的にはコーディングする際にcssを確認する際に使わせてもらっています。
また、VS Codeとの連携も拡張機能として登場したので、こちらも入れて利用しています。
FigmaとVS Codeとの行き来をしなくて良くなるのでとても便利です。
https://marketplace.visualstudio.com/items?itemName=figma.figma-vscode-extension

バリアブル(Beta)の追加

変数を利用したデザインを作成することができるようになります。
まだ利用できていませんが、紹介動画を見るとめちゃくちゃワクワクする機能でした。

色、数値、文字列などの変数を設定できるようになるので、ワンクリックでさまざまなパターンのデザインを作成することが可能になるようです。

変数を用意するのが少し大変そうですが、少しずつ取り入れていきたいと思います。

オートレイアウトの折り返しの追加

個人的に一番望んでいた機能が追加されました!
オートレイアウトで折り返しが指定できるようになりました。

また、フレームの最小・最大値も合わせて設定することでレスポンシブのイメージなども柔軟に対応できるようになります。

フォントのプレビュー表示

これは地味にありがたい機能追加でした。
今まではプラグインでプレビュー表示することしかできませんでしたが、標準機能として提供されるようになりました。
わりと使用頻度が高いのでストレスフリーになってよかったです。

さいごに

今回紹介した新機能は一部ですが、それでも作業効率がアップすること間違いなし!な機能が沢山リリースされました。

高度な機能も増えてきたので、日々手を動かしながら使いこなせるように頑張ろうと思います💪


cssの「display」が新しい2値構文に。「display: block flow」とは?

「display」プロパティが2値構文が使えるということで調べてみました。

結論から言うと、「今すぐ何かしないといけない」とか「新しくなにかできるメリット」などはありません。
 

それぞれの 2 値版は旧来版に直接マッピングされているので、 2 値版を使用するメリットは今のところありません。

引用:display の古い値について

・・・なるほど。

・・・メリットなしか。

とはいえ今後、戸惑わないためにも概要を調べました。

「display:block」は「display:block flow」というような、2値構文の書き方ができるようになります。

1つ目の値は「ブロック要素」なのか「インライン要素」なのか指定します。
設定できる値は

inline, block, run-in
です。

2つ目の値は内側の「レイアウト」方法を指定します。
設定できる値は

flow,flow-root,table,flex,grid,ruby
です。

この2つ目の値のデフォルトは「flow」で、それは「フローレイアウト」になります。
並べるだけと想像すると分かりやすいかもしれません。

つまり「display:block」は「display:block flow」ということになります。

それ以外の今までの値と新しい値を比べると使い方が想像しやすいです。

単一の値新しい値
blockblock flow
inlineinline flow
inline-blockinline flow-root
flexblock flex
inline-flexinline flex
gridblock grid
inline-gridinline grid
flow-rootblock flow-root

今回は、ChromeとEdgeは7月リリース予定の115でサポートされ、SafariとFirefoxでは既にサポート済みのdisplayの新しい2値構文の書き方について紹介しました。