Есть ли хороший способ перебора символов строки? Я хотел бы иметь возможность делать foreach
, array_map
, array_walk
, array_filter
и т. Д. Для символов строки.
Тип casting / juggling не получал меня нигде (помещал всю строку как один элемент массива), и лучшее решение, которое я нашел, просто использует цикл 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) Лучший способ построить массив символов из строки (и если да, то как насчет другого направления?)
Я чувствую, что я потерял что-то очевидное здесь.
Как насчет str_split
?
Если ваши строки находятся в 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 ); }
Итерационная строка:
for ($i = 0; $i < strlen($str); $i++){ echo $str[$i]; }
Выпущенный из ответа @SeaBrightSystems, вы можете попробовать следующее:
$s1 = "textasstringwoohoo"; $arr = str_split($s1); //$arr now has character array
Вы также можете просто получить доступ к $ s1 как массив, если вам нужно только получить к нему доступ:
$s1 = "hello world"; echo $s1[0]; // -> h
Для тех, кто ищет быстрый способ перебора строк в php, Ive подготовил тестовое тестирование.
Первый способ, с помощью которого вы напрямую обращаетесь к строковым символам, указав свою позицию в скобках и обрабатывая строку как массив:
$string = "a sample string for testing"; $char = $string[4] // equals to m
Я сам думал, что последний – самый быстрый метод, но я был неправ.
Как и во втором методе (который используется в принятом ответе):
$string = "a sample string for testing"; $string = str_split($string); $char = $string[4] // equals to m
Этот метод будет более быстрым, потому что мы используем реальный массив и не предполагаем, что он является массивом.
Вызов последней строки каждого из вышеперечисленных методов за 1000000
раз приводит к этим результатам бенчмаркинга:
Использование строки [i]
0.24960017204285 Seconds
Использование str_split
0.18720006942749 Seconds
Это означает, что второй метод работает быстрее.
// 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; }