2011-01-05 37 views
69

Có cách nào tốt đẹp để lặp lại các ký tự của chuỗi không? Tôi muốn có thể làm foreach, array_map, array_walk, array_filter v.v. trên các ký tự của một chuỗi.PHP - lặp lại trên các ký tự chuỗi

Loại đúc/tung hứng không đưa tôi đến bất kỳ đâu (đặt toàn bộ chuỗi như một phần tử của mảng) và giải pháp tốt nhất mà tôi đã tìm thấy đơn giản là sử dụng vòng lặp for để tạo mảng. Nó cảm thấy như có nên có một cái gì đó tốt hơn. Ý tôi là, nếu bạn có thể lập chỉ mục trên nó, bạn cũng không thể lặp lại được không?

Đây là tốt nhất mà tôi đã có

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); 

Có một trong hai:

A) Một cách để làm cho chuỗi iterable
B) Một cách tốt hơn để xây dựng các mảng nhân vật từ chuỗi (và nếu vậy, làm thế nào về hướng khác?)

Tôi cảm thấy như im thiếu một cái gì đó hiển nhiên ở đây.

+0

Có lẽ bạn nên nói thêm về điều bạn đang cố gắng để hoàn thành ... nó có vẻ như có thể có một cách tốt hơn để làm điều đó bằng chuỗi hoạt động bình thường. –

+0

không có mục tiêu thực sự ở đây. chỉ là một sự tò mò tôi đang chơi với. có vẻ lạ rằng mặc dù bạn có thể lập chỉ mục trên các chuỗi bạn không thể lặp lại. Tôi đã thất bại trong việc nghĩ đến việc sử dụng ví dụ có ý nghĩa, nhưng tôi vẫn muốn biết nếu có một số cách để lặp lại các ký tự dây mà không cần xây dựng một mảng ký tự explictly –

+0

đó là điểm tốt, rõ ràng là ví dụ của tôi khá nông. nghĩa là - hầu hết mọi thứ bạn làm với 'array_filter' trong ý nghĩa này có thể được thực hiện tốt hơn với các hàm chuỗi hoặc hàm reg-ex –

Trả lời

89

Bước 1: chuyển đổi chuỗi thành một mảng bằng cách sử dụng str_split chức năng

$array = str_split($your_string);

Bước 2: lặp qua mảng mới được tạo ra

foreach ($array as $char) { 
echo $char; 
} 

Bạn có thể kiểm tra Tài liệu PHP để biết thêm thông tin: str_split

+0

hah wow. vâng nó. và tất nhiên implode có thể làm theo hướng khác. Tôi sẽ chấp nhận điều này sớm trừ khi ai đó có thể hiển thị một cách để thực hiện lặp lại ngay trên sting –

+0

@jon_darkstar Tôi không biết ứng dụng của bạn, nhưng lưu ý rằng mỗi mục nhập trong một mảng có chi phí đáng kể (4bytes IIRC). Bỏ qua điều đó, đó là cách 'khá' hơn: http://nikic.github.com/2011/12/12/How-big-are-PHP-arrays-really-Hint-BIG.html –

19

Nếu dây của bạn trong Unicode bạn nên sử dụng preg_split với /u modifier

Từ ý kiến ​​trong tài liệ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); 
} 
+0

Đối với chuỗi nhiều byte, ' mb_split' đáng tin cậy hơn. – Xenon

5

mở rộng từ @SeaBrightSystems trả lời, bạn có thể thử này:

$s1 = "textasstringwoohoo"; 
$arr = str_split($s1); //$arr now has character array 
+0

Bị bỏ phiếu vì câu trả lời này không thêm giá trị. Câu trả lời @SeaBrightSystems đã chứa tất cả thông tin cần thiết và liên kết đến tài liệu. –

+0

Tôi không đồng ý, câu trả lời này làm tăng thêm giá trị, nó đưa ra một ví dụ làm việc về cách str_split có thể làm việc trong một ứng dụng PHP. @SeaBrightSystems chỉ liên kết đến tài liệu, đôi khi không hữu ích khi một người đang cố gắng xem cách một hàm có thể hoạt động, được đưa ra một ví dụ. Nếu không, hầu hết các câu trả lời SO chỉ là các liên kết đến php.net – kurdtpage

+0

@kurdtpage Tài liệu php là một trong những tài liệu tốt nhất mà tôi biết. Có nhiều ví dụ rất tốt cho mọi hàm và các ví dụ cho 'str_split' là cách chi tiết hơn ví dụ của anh ta. –

6

Bạn cũng có thể truy cập $ s1 như một mảng, nếu bạn chỉ cần truy cập vào nó:

$s1 = "hello world"; 
echo $s1[0]; // -> h 
0
// 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; 
} 
2

Đối với những người đang tìm cách nhanh nhất để lặp qua chuỗi trong php, Ive đã chuẩn bị thử nghiệm điểm chuẩn.
Phương pháp đầu tiên mà bạn truy cập vào ký tự chuỗi trực tiếp bằng cách xác định vị trí của nó trong ngoặc đơn và xử lý chuỗi như một mảng:

$string = "a sample string for testing"; 
$char = $string[4] // equals to m 

Bản thân tôi nghĩ sau này là phương pháp nhanh nhất, nhưng tôi đã sai.
Như với phương pháp thứ hai (được sử dụng trong các câu trả lời được chấp nhận):

$string = "a sample string for testing"; 
$string = str_split($string); 
$char = $string[4] // equals to m 

Phương pháp này sẽ là nhanh hơn vì chúng ta đang sử dụng một mảng thực và không thừa nhận một đến là một mảng.

Calling dòng cuối cùng của mỗi người trong số các phương pháp trên cho 1000000 lần dẫn đến những kết quả benchmark:

Sử dụng string [i]
0.24960017204285 Seconds

Sử dụng str_split
0.18720006942749 Seconds

Có nghĩa là phương pháp thứ hai là cách nhanh hơn.

25

Lặp chuỗi:

for ($i = 0; $i < strlen($str); $i++){ 
    echo $str[$i]; 
} 
+1

Điều này có vẻ như là một câu trả lời tốt hơn vì nó trả lời câu hỏi - tức là cách lặp qua chuỗi thay vì 'chuyển đổi thành mảng'. – Robin

Các vấn đề liên quan