PHPの標準機能でもアローラロコンをアーロンにできるのだが、SymfonyのString Componentというやつがちょっとおしゃれな文字列演算を提供しているので、せっかくなのでこれを使ってみよう。
Symfony String Componentとは
だいたいドキュメントを見ればわかる。
Symfony StringはByteString
CodePointString
UnicodeString
という3種類のクラスを用意しているが、基本はUnicodeString
が扱う書記素(grapheme)という単位で扱うのがいいだろう。
Stringオブジェクトを作る
普通の文字列値をStringオブジェクトに変えるにはnew
で新しいインスタンスを作る方法とヘルパー関数を使う方法がある。
まあ、こだわりがなければヘルパー関数を使っておくと見ためがすっきりするだろう。
<?php
use function Symfony\Component\String\u;
$str = u('アローラロコン');
//=> Symfony\Component\String\UnicodeString {#2673}
u
という短かすぎる関数名が趣味に合わなければ、 use function Symfony\Component\String\u as unicode;
のようにすると、そのファイル内では unicode('文字列')
のように扱える。
さて、Symfony Stringオブジェクトは(string)
キャストすると普通の文字列値に戻せる。
>>> (string)$str
//=> "アローラロコン"
chunkとarray_map()とsliceを使う方法
<?php
use function Symfony\Component\String\u;
echo implode(array_map(fn($s) => $s->slice(0, 1), u('アローラロコン')->chunk(2)));
- 元の文字列をSymfonyの
UnicodeString
にするu('アローラロコン')
-
UnicodeString::chunk()
で文字列を分解する[u('アロ'), u('ーラ'), u('ロコ'), u('ン')]
-
array_map()
でそれぞれの要素からUnicodeString::slice()
で1文字だけ抜き出す[u('ア'), u('ー'), u('ロ'), u('ン')]
-
implode()
を1個の文字列に結合する'アーロン'
- 配列の要素は
string
ではなくUnicodeString
オブジェクトなのだが、implode()
関数は配列要素がstring
ではなかったときに(string)
キャストしてくれる- 内部的には
UnicodeString::__toString()
マジックメソッドが呼ばれている
- 内部的には
- 完成!
UnicodeStrging::join()
というメソッドもあり、これを使うとstring
にキャストせずUnicodeString
のまま結合できるのだが、今回はそのまま出力するので標準関数のimplode()
をそのまま呼んでしまってよい。
echo u('')->join(array_map(fn($s) => $s->slice(0, 1), u('アローラロコン')->chunk(2)));
chunkとarray_chunk()とarray_column()を使う方法
<?php
use function Symfony\Component\String\u;
echo implode(array_column(array_chunk(u('アローラロコン')->chunk(), 2), 0));
PHPの解法とほとんど変わらないので手順は割愛する。手数は一見多そうだがコードとしてはarray_map()
を噛ませるよりちょっぴり短い。
動作確認
https://phpsandbox.io/n/lively-forest-ddgd-3shiu にまとめてある。
余談だが、普段オンラインサンドボックス環境で使っている3v4lは軽量かつPHPの複数バージョンを同時実行できて便利だが、ライブラリに依存したコードが書けない。phpsandbox.ioは任意のComposerパッケージを追加した状態で実行できるので、場合によって使い分けるのがいいだろう。
まとめ
文字列処理にはSymfony Stringを使え。
なんかもうちょっと短く書ける解法がありそうな気もするのでSymfonyマスターのひとは教えてください。