Đảo ngược thứ tự các mục trong danh sách foreach


83

Tôi muốn đảo ngược thứ tự của các mục trong danh sách của mã này. Về cơ bản, đó là một tập hợp các năm từ lâu đời nhất đến gần đây và tôi đang cố gắng đảo ngược kết quả đó.

<?php
    $j=1;     
    foreach ( $skills_nav as $skill ) {
        $a = '<li><a href="#" data-filter=".'.$skill->slug.'">';
        $a .= $skill->name;                 
        $a .= '</a></li>';
        echo $a;
        echo "\n";
        $j++;
    }
?>  

Câu trả lời:


178

Đi bộ về phía sau

Nếu bạn đang tìm kiếm một giải pháp PHP thuần túy, bạn cũng có thể chỉ cần đếm ngược thông qua danh sách, truy cập từ trước đến sau:

$accounts = Array(
  '@jonathansampson',
  '@f12devtools',
  '@ieanswers'
);

$index = count($accounts);

while($index) {
  echo sprintf("<li>%s</li>", $accounts[--$index]);
}

Ở trên đặt $indexthành tổng số phần tử và sau đó bắt đầu truy cập chúng từ trước trở lại, giảm giá trị chỉ mục cho lần lặp tiếp theo.

Đảo ngược mảng

Bạn cũng có thể tận dụng array_reversehàm để đảo ngược các giá trị trong mảng của mình, cho phép bạn truy cập chúng theo thứ tự ngược lại:

$accounts = Array(
  '@jonathansampson',
  '@f12devtools',
  '@ieanswers'
);

foreach ( array_reverse($accounts) as $account ) {
  echo sprintf("<li>%s</li>", $account);
}

2
@Slawek Nếu mảng đã được sắp xếp thứ tự, tại sao việc đảo ngược lại nhất thiết phải tốt hơn là đếm ngược?
Sampson

1
Tuyệt vời, array_reverse đã hoạt động! Cảm ơn Jonathan và mọi người khác.
blkedy

4
@JonathanSampson - bởi vì nếu bạn đảo ngược mảng trước khi sử dụng nó trong vòng lặp, bạn chỉ cần thay đổi nó trong tương lai. Khi bạn liên kết logic vòng lặp với dữ liệu, thứ tự thay đổi sẽ buộc thay đổi vòng lặp.
Slawek

1
@Slawek Tôi không chắc mình theo dõi. Đếm ngược thông qua một mảng là một thực tế phổ biến và không cần thận trọng khi xử lý mảng trong tương lai vì nó không thực sự sửa đổi mảng.
Sampson

1
@Slawek Tôi không bất đồng ở đó. Tôi nghĩ rằng tôi không thấy bất kỳ dấu hiệu nào cho thấy người dùng đang tuân theo bất kỳ loại mô hình MVC nào. Chắc chắn, nếu họ có một bộ điều khiển hoặc một mô hình, có thể sẽ khôn ngoan hơn nếu sắp xếp mảng ở đó trong nhiều trường hợp.
Sampson


20

array_reverse()không thay đổi mảng nguồn, nhưng trả về một mảng mới. (Xem array_reverse().) Vì vậy, bạn cần phải lưu trữ mảng mới trước hoặc chỉ sử dụng hàm trong phần khai báo của vòng lặp for.

<?php 
    $input = array('a', 'b', 'c');
    foreach (array_reverse($input) as $value) {
        echo $value."\n";
    }
?>

Đầu ra sẽ là:

c
b
a

Vì vậy, để chuyển địa chỉ tới OP, mã sẽ trở thành:

<?php
    $j=1;     
    foreach ( array_reverse($skills_nav) as $skill ) {
        $a = '<li><a href="#" data-filter=".'.$skill->slug.'">';
        $a .= $skill->name;                 
        $a .= '</a></li>';
        echo $a;
        echo "\n";
        $j++;
}

Cuối cùng, tôi sẽ đoán rằng đó $jlà một bộ đếm được sử dụng trong nỗ lực ban đầu để có được bước đi ngược lại $skills_navhoặc một cách để đếm $skills_navmảng. Nếu trước đây, nó nên được loại bỏ bây giờ để bạn có giải pháp chính xác. Nếu cái sau, nó có thể được thay thế, bên ngoài vòng lặp, bằng một $j = count($skills_nav).


7

Nếu bạn không ngại phá hủy mảng (hoặc một bản sao tạm thời của nó), bạn có thể làm:

$stack = array("orange", "banana", "apple", "raspberry");

while ($fruit = array_pop($stack)){
    echo $fruit . "\n<br>"; 
}

sản xuất:

raspberry 
apple 
banana 
orange 

Tôi nghĩ rằng giải pháp này đọc rõ ràng hơn so với việc tìm kiếm một chỉ mục và bạn ít có khả năng mắc lỗi xử lý chỉ mục hơn, nhưng vấn đề với nó là mã của bạn có thể sẽ mất nhiều thời gian hơn để chạy nếu bạn phải tạo một bản sao tạm thời của mảng trước. . Tìm kiếm một chỉ mục có khả năng chạy nhanh hơn và nó cũng có thể hữu ích nếu bạn thực sự cần tham khảo chỉ mục, như trong:

$stack = array("orange", "banana", "apple", "raspberry");
$index = count($stack) - 1;
while($index > -1){
    echo $stack[$index] ." is in position ". $index . "\n<br>";
    $index--;
} 

Nhưng như bạn thấy, bạn phải rất cẩn thận với chỉ mục ...


1
Các array_popcách tiếp cận là chậm hơn so với 3 lần array_reversetiếp cận: 3v4l.org/3jaTT
Finesse

4

Giả sử bạn chỉ cần đảo ngược một mảng được lập chỉ mục (không liên kết hoặc đa chiều) thì một vòng lặp for đơn giản sẽ đủ:

$fruits = ['bananas', 'apples', 'pears'];
for($i = count($fruits)-1; $i >= 0; $i--) {
    echo $fruits[$i] . '<br>';
} 

3

Bạn có thể sử dụng hàm usort để tạo các quy tắc sắp xếp riêng


1

Nếu mảng của bạn được điền thông qua Truy vấn SQL, hãy xem xét việc đảo ngược kết quả trong MySQL, tức là:

SELECT * FROM model_input order by creation_date desc

-1
<?php
    $j=1; 


      array_reverse($skills_nav);   


    foreach ( $skills_nav as $skill ) {
        $a = '<li><a href="#" data-filter=".'.$skill->slug.'">';
        $a .= $skill->name;                 
        $a .= '</a></li>';
        echo $a;
        echo "\n";
        $j++;
    }
?> 

1
array_reverse () không thay đổi mảng nguồn, nhưng trả về một mảng mới.
Cláudio Silva
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.