Есть ли хороший способ перебора символов строки? Я хотел бы иметь возможность делать 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) Лучший способ построить массив символов из строки (и если да, то как насчет другого направления?)
Мне кажется, что у меня что-то не так очевидно.
Ответ 1
Шаг 1: преобразовать строку в массив с str_split
функции str_split
$array = str_split($your_string);
Шаг 2: цикл по вновь созданному массиву
foreach ($array as $char) {
echo $char;
}
Вы можете проверить PHP документацию для получения дополнительной информации: str_split
Ответ 2
Итерация строки:
for ($i = 0; $i < strlen($str); $i++){
echo $str[$i];
}
Ответ 3
Если ваши строки находятся в Юникоде, вы должны использовать 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 );
}
Ответ 4
Вы также можете просто получить доступ к $s1 как массив, если вам нужно только получить к нему доступ:
$s1 = "hello world";
echo $s1[0]; // -> h
Ответ 5
Развернутый из @SeaBrightSystems ответ, вы можете попробовать следующее:
$s1 = "textasstringwoohoo";
$arr = str_split($s1); //$arr now has character array
Ответ 6
Для тех, кто ищет быстрый способ перебора строк в 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
Этот метод будет более быстрым, потому что мы используем массив real и не предполагаем, что он является массивом.
Вызов последней строки каждого из приведенных выше методов для 1000000
раз приводит к этим результатам бенчмаркинга:
Использование строки [i]
0.24960017204285 Seconds
Использование str_split
0.18720006942749 Seconds
Это означает, что второй метод работает быстрее.
Ответ 7
Хм... Нет необходимости усложнять вещи. Основы работают отлично всегда.
$string = 'abcdef';
$len = strlen( $string );
$x = 0;
Прямое направление:
while ( $len > $x ) echo $string[ $x++ ];
Выходы: abcdef
Обратное направление:
while ( $len ) echo $string[ --$len ];
Выходы: fedcba
Ответ 8
// 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;
}
Ответ 9
Большинство ответов забыли о неанглийских символах !!!
strlen
считает бАЙТЫ, а не символы, поэтому он и его родственные функции отлично работают с английскими символами, поскольку английские символы хранятся в 1 байте в кодировках UTF-8 и ASCII, вам необходимо использовать многобайтовый код строковые функции mb_*
Это будет работать с любым символом, закодированным в UTF-8
// 8 characters in 12 bytes
$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) "ث"