Sau array_filter (), làm cách nào để đặt lại các phím theo thứ tự số bắt đầu từ 0


108

Tôi vừa sử dụng array_filter để xóa các mục nhập chỉ có giá trị '' khỏi một mảng và bây giờ tôi muốn áp dụng một số biến đổi nhất định trên nó tùy thuộc vào trình giữ chỗ bắt đầu từ 0, nhưng rất tiếc là nó vẫn giữ lại chỉ mục ban đầu. Tôi nhìn một lúc và không thấy gì cả, có lẽ tôi đã bỏ lỡ điều hiển nhiên, nhưng câu hỏi của tôi là ...

Làm cách nào để tôi có thể dễ dàng đặt lại các chỉ mục của mảng bắt đầu từ 0 và đi theo thứ tự trong mảng MỚI, thay vì giữ lại các chỉ mục cũ?



Trừ khi bạn hoàn toàn chắc chắn rằng bạn không có bất kỳ giá trị nào trống / không-ish / falsey trong mảng của mình, tôi phải khuyến khích bạn không sử dụng array_filter()- bạn có thể xóa nhiều hơn bạn dự định. Dưới đây là một số giải thích với một bản demo: stackoverflow.com/a/43657056/2943403
mickmackusa

Câu trả lời:



37

Nếu bạn đang sử dụng bộ lọc Mảng, hãy làm như sau

$NewArray = array_values(array_filter($OldArray));

3
Oh thời gian tôi đã mất cố gắng tìm ra lý do tại sao kết quả của json_encode một mảng là khác nhau hơn so với các json_encode một mảng array_filtered ... cảm ơn bạn rất nhiều ...
Jerther

13

Tôi lo lắng về việc có bao nhiêu lập trình viên đã vô tội sao chép / dán array_values(array_filter())phương thức vào mã của họ - Tôi tự hỏi có bao nhiêu lập trình viên vô tình gặp sự cố vì lòng tham của array_filter. Hoặc tệ hơn, có bao nhiêu người không bao giờ phát hiện ra rằng hàm xóa quá nhiều giá trị khỏi mảng ...

Tôi sẽ trình bày một giải pháp thay thế tốt hơn cho quy trình gồm hai phần là tách NULLcác phần tử khỏi một mảng và lập chỉ mục lại các khóa.

Tuy nhiên, trước tiên, điều cực kỳ quan trọng là tôi phải nhấn mạnh bản chất tham lam array_filter()và cách điều này có thể âm thầm phá hỏng dự án của bạn. Đây là một mảng có các giá trị hỗn hợp trong đó sẽ gây ra rắc rối:

$array=['foo',NULL,'bar',0,false,null,'0',''];

Giá trị rỗng sẽ bị loại bỏ bất kể chữ hoa / thường.

Nhưng hãy nhìn vào những gì còn lại trong mảng khi chúng ta sử dụng array_values ​​() & array_filter () :

array_values(array_filter($array));

Mảng đầu ra ($ mảng):

array (
  0 => 'foo',
  1 => 'bar'
)
// All empty, zero-ish, falsey values were removed too!!!

Bây giờ hãy xem những gì bạn nhận được với phương thức của tôi sử dụng array_walk () & is_null () để tạo một mảng mới được lọc:

array_walk($array,function($v)use(&$filtered){if(!is_null($v)){$filtered[]=$v;}});

Điều này có thể được viết trên nhiều dòng để dễ đọc / giải thích hơn:

array_walk(                      // iterate each element of an input array
    $array,                      // this is the input array
    function($v)use(&$filtered){ // $v is each value, $filter (output) is declared/modifiable
        if(!is_null($v)){        // this literally checks for null values
            $filtered[]=$v;      // value is pushed into output with new indexes
        }
    }
);

Mảng đầu ra ($ filter):

array (
  0 => 'foo',
  1 => 'bar',
  2 => 0,
  3 => false,
  4 => '0',
  5 => '',
)

Với phương pháp của tôi, bạn nhận được các khóa được lập chỉ mục lại của mình, tất cả các giá trị không phải null và không có giá trị nào trong số các giá trị rỗng. Một lớp lót sạch, di động, đáng tin cậy cho tất cả các nhu cầu lọc null mảng của bạn. Đây là một cuộc biểu tình .



Tương tự, nếu bạn muốn loại bỏ các phần tử rỗng, false và null (giữ lại các số không), bốn phương pháp này sẽ hoạt động:

var_export(array_values(array_diff($array,[''])));

hoặc là

var_export(array_values(array_diff($array,[null])));

hoặc là

var_export(array_values(array_diff($array,[false])));

hoặc là

var_export(array_values(array_filter($array,'strlen')));

Đầu ra:

array (
  0 => 'foo',
  1 => 'bar',
  2 => 0,
  3 => '0',
)

Cuối cùng, đối với bất kỳ ai thích cú pháp của cấu trúc ngôn ngữ, bạn cũng có thể chỉ cần đẩy các giá trị đủ điều kiện vào một mảng mới để tạo chỉ mục mới.

$array=['foo', NULL, 'bar', 0, false, null, '0', ''];

$result = [];
foreach ($array as $value) {
    if (strlen($value)) {
        $result[] = $value;
    }
}

var_export($result);

2
Nếu bạn viết array_values(array_filter($arr, function($el) {return $el !== '';}))thì mọi thứ sẽ không hoạt động theo đúng như mong đợi phải không? Đó dường như là cách tự nhiên để thực hiện những gì OP đang yêu cầu.
Casey

1
Đúng. Quan điểm của tôi là các nhà phát triển nên tránh sự thôi thúc sử dụng hành vi mặc định array_filter()trừ khi kiến ​​thức sâu sắc của họ về dữ liệu cho phép lọc tham lam mà không có tác dụng phụ. (Một cách thận trọng hơn nữa: empty()cư xử trong cùng một thời trang này và cũng bao gồm một mảng trống trong sự tham lam của mình.)
mickmackusa

2
Câu trả lời này trả lời câu hỏi hoàn toàn khác, không liên quan đến câu trả lời ban đầu theo bất kỳ cách nào, hình dạng hay hình thức nào.
AnrDaemon

1
array_filter()hoạt động chính xác như bạn mong đợi dựa trên những gì nó nói trong sách hướng dẫn: php.net/manual/en/ Chức năng.array-filter.php "Nếu không có lệnh gọi lại nào được cung cấp, tất cả các mục nhập của mảng bằng FALSE (xem chuyển đổi thành boolean ) sẽ được gỡ bỏ." Và các lập trình viên PHP nên biết rằng 0, null, false, '' và '0' đều đánh giá là false khi bị ép buộc với boolean.
madsen

1
Điều là, hầu hết mọi người không biết những gì mong đợi. Bạn có, tôi làm, nhưng nhiều người thì không. Tôi đăng câu trả lời này để giúp những người không biết.
mickmackusa

12

Sử dụng array_values():

<?php

$array = array('foo', 'bar', 'baz');
$array = array_filter($array, function ($var) {
    return $var !== 'bar';
});

print_r($array); // indexes 0 and 2
print_r(array_values($array)); // indexes 0 and 1
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.