Chạy một vòng lặp n lần (n là số nguyên dương).

1. Vòng lặp for

Vòng lặp cơ bản nhất và thường được dùng nhất khi giải quyết vấn đề trên, nhưng lại là vòng lặp hay gặp lỗi nhất vì:

  1. Dùng phép so sánh làm điều kiện dừng vòng lặp, dễ gây nhầm lẫn < <= > >=
  2. Phải khởi tạo giá trị bắt đầu và quyết định số bước nhảy ngay cả khi không cần thiết (thường là +=1)
  3. Syntax khá rườm rà
$n = 100;
for ($i = 0; $i < $n; $i++) {
    echo $i; // 100 lần từ 0 đến 99
}

Trong trường hợp muốn kết thúc vòng lặp khi giá trị của i bằng n ta phải đổi giá trị khởi tạo của i là 1 và thay < bằng <=:

$n = 100;
for ($i = 1; $i <= $n; $i++) {
    echo $i; // 100 lần từ 1 đến 100
}

Nếu bạn không tăng giá trị khởi tạo của i  lên 1 thì  vòng lặp sẽ chạy từ 0 đến 100 (101 lần) là sai đề bài. Trong trường hợp các bước nhảy (step) của i khác 1, hãy xét đoạn code này:

$n = 100;
$step = 2;
$count = 0;
for ($i = 0; $i < $n; $i += $step) {
    $count++;
}
echo $count; // 50 lần

Nếu ta thay n bằng 99, vòng lặp trên vẫn chạy 50 lần. Như vậy không những sai đề bài mà còn chạy số lần không nhất quán với n.

Để giải quyết vấn đề này thì ta hãy dùng $i < $n * $step thay vì dùng điều kiện $i < $n:

$n = 1234;
$step = 6;
$count = 0;
for ($i = 0; $i < $n * $step; $i += $step) {
    $count++;
}
echo $count; // chính xác 1234 lần

2. Vòng lặp while

Một thời gian dài tôi thích dùng while, đơn giản vì nó trông nguy hiểm hơn :))

$n = 100;
$i = 0;
while ($i++ < $n) {
    echo $i; // 100 lần từ 1 đến 100
}

Cần chú ý là $i++ và ++$i sẽ cho ra kết quả khác nhau:

$n = 100;
$i = 0;
while (++$i < $n) {
    echo $i; // 99 lần từ 1 đến 99
}

Lý do của sự khác nhau này là ở lần so sánh cuối cùng, ++$i có giá trị là 100 (cộng trước khi so sánh) cho nên không thoả mãn điều kiện $i < $n.

Một cách thông minh hơn để sử dụng while là đi ngược từ n về 0:

$n = 100;
while ($n-- > 0) {
    echo $n; // 100 lần từ 99 về 0
}

3. Kết hợp foreach và range

foreach chủ yếu được dùng để duyệt mảng, cho nên ta sẽ dùng kết hợp với mảng để giải quyết bài toán trên, và tôi thực sự thích dùng cách này nhất.

$n = 100;
foreach (range(1, $n) as $i) {
    echo $i; // 100 lần từ 1 đến 100
}

Để dễ hiểu hơn tôi sẽ nói một chút về hàm range, cách sử dụng hàm range như sau:

function range ($low, $high, $step = null)
// $low là số nhỏ nhất
// $high là số lớn nhất
// $step là bước nhảy, giá trị phải là số nguyên 
// và nếu không được truyền giá trị thì nó sẽ bằng 1 nhé

Như vậy thì đoạn code phía trên sẽ duyệt mảng 100 item [1,2,3,...100].

Lý do tôi thích cách này vì nó ít code hơn, ít gây nhầm lẫn do loại bỏ đươc phép so sánh và đặc biệt có thể đặt số bước ngay bên trong hàm range khi cần thiết. Ví dụ với step bằng 6 ta có đoạn code dưới đây:

$n = 1234;
$step = 6;
$count = 0;
foreach (range(1, $n * $step, $step) as $i) {
    $count++;
}
echo $count; // 1234 lần

Cần chú ý là cách kết hợp foreach và range này cho performance không cao, vì phải tạo ra 1 mảng gây tốn bộ nhớ, nhất là khi đó là một mảng cực lớn. Tuy vậy range sẽ không tạo lại 1 mảng mới sau mỗi vòng lặp. Cho nên bạn không cần phải gọi hàm range ở ngoài biểu thức đâu nhé. Ví dụ như dưới đây:

$n = 1234;
$step = 6;
$count = 0;
$range = range(1, $n * $step, $step); // không cần phải làm thế này
foreach ($range as $i) { // hãy viết range() luôn ở dòng này
    $count++;
}
echo $count; // 1234 lần

Bài viết đến đây là hết. Hãy comment cách mà bạn hay dùng ở phía dưới nhé.

0 0 votes
Article Rating