文字列の文字を繰り返す良い方法はありますか?文字列の文字に対してforeach
、array_map
、array_walk
、array_filter
などを実行できるようにしたいと思います。
型キャスト/ジャグリングでは何も得られませんでした(文字列全体を配列の1つの要素として入力します)。私が見つけた最良の解決策は、単純にforループを使用して配列を構築することです。もっと良いものがあるはずです。つまり、インデックスを作成できるのであれば、同様に反復できるはずではありませんか?
これは私が持っている最高の
function stringToArray($s)
{
$r = array();
for($i=0; $i<strlen($s); $i++)
$r[$i] = $s[$i];
return $r;
}
$s1 = "textasstringwoohoo";
$arr = stringToArray($s1); //$arr now has character array
$ascval = array_map('ord', $arr); //so i can do stuff like this
$foreach ($arr as $curChar) {....}
$evenAsciiOnly = array_filter( function($x) {return ord($x) % 2 === 0;}, $arr);
どちらかあります:
A)文字列を反復可能にする方法
B)文字列から文字配列を作成するより良い方法(もしそうなら、他の方向はどうですか?)
ここで明らかな何かを見逃しているような気がします。
ステップ1:str_split
関数を使用して文字列を配列に変換します
$array = str_split($your_string);
ステップ2:新しく作成された配列をループします
foreach ($array as $char) {
echo $char;
}
詳細については、PHPのドキュメントを確認できます。 str_split
文字列の反復:
for ($i = 0; $i < strlen($str); $i++){
echo $str[$i];
}
文字列がUnicodeの場合、preg_split
を/u
修飾子とともに使用する必要があります
PHPドキュメントのコメントから:
function mb_str_split( $string ) {
# Split at all position not after the start: ^
# and not before the end: $
return preg_split('/(?<!^)(?!$)/u', $string );
}
アクセスするだけの場合は、配列のように$ s1にアクセスすることもできます。
$s1 = "hello world";
echo $s1[0]; // -> h
@SeaBrightSystemsの回答から展開して、これを試すことができます:
$s1 = "textasstringwoohoo";
$arr = str_split($s1); //$arr now has character array
PHPで文字列を反復処理する最速の方法を探している人のために、Iveはベンチマークテストを準備しました。
ブラケット内の位置を指定し、文字列を配列のように扱うことにより、文字列の文字に直接アクセスする最初の方法:
$string = "a sample string for testing";
$char = $string[4] // equals to m
私は後者が最速の方法だと思ったが、間違っていた。
2番目の方法(受け入れられた回答で使用)と同様:
$string = "a sample string for testing";
$string = str_split($string);
$char = $string[4] // equals to m
このメソッドは、real配列を使用し、配列であると想定しないため、より高速になります。
上記の各メソッドの最後の行を1000000
回呼び出すと、これらのベンチマーク結果が得られます。
string [i]を使用0.24960017204285 Seconds
str_splitの使用0.18720006942749 Seconds
つまり、2番目の方法の方がはるかに高速です。
うーん...物事を複雑にする必要はありません。基本は常にうまく機能します。
$string = 'abcdef';
$len = strlen( $string );
$x = 0;
順方向:
while ( $len > $x ) echo $string[ $x++ ];
出力:abcdef
逆方向:
while ( $len ) echo $string[ --$len ];
出力:fedcba
// Unicode Codepoint Escape Syntax in PHP 7.0
$str = "cat!\u{1F431}";
// IIFE (Immediately Invoked Function Expression) in PHP 7.0
$gen = (function(string $str) {
for ($i = 0, $len = mb_strlen($str); $i < $len; ++$i) {
yield mb_substr($str, $i, 1);
}
})($str);
var_dump(
true === $gen instanceof Traversable,
// PHP 7.1
true === is_iterable($gen)
);
foreach ($gen as $char) {
echo $char, PHP_EOL;
}
回答のほとんどは、英語以外の文字を忘れていました!!!
strlen
は文字ではなくBYTESをカウントするので、英語の文字はUTF-8とASCIIエンコードの両方で1バイトに格納されるため、兄弟関数は英語の文字で問題なく動作します。 マルチバイト文字列関数mb_*
を使用する必要があります
これは、UTF-8
でエンコードされたany文字で動作します
$string = "abcdأبتث";
$charsCount = mb_strlen($string, 'UTF-8');
for($i = 0; $i < $charsCount; $i++){
$char = mb_substr($string, $i, 1, 'UTF-8');
var_dump($char);
}
この 出力
string(1) "a"
string(1) "b"
string(1) "c"
string(1) "d"
string(2) "أ"
string(2) "ب"
string(2) "ت"
string(2) "ث"