Setelah array_filter (), bagaimana cara mereset kunci agar masuk dalam urutan numerik mulai dari 0

108

Saya baru saja menggunakan array_filter untuk menghapus entri yang hanya memiliki nilai '' dari array, dan sekarang saya ingin menerapkan transformasi tertentu di atasnya tergantung pada placeholder mulai dari 0, tetapi sayangnya itu masih mempertahankan indeks asli. Saya mencari beberapa saat dan tidak dapat melihat apa-apa, mungkin saya hanya melewatkan yang sudah jelas, tetapi pertanyaan saya adalah ...

Bagaimana saya dapat dengan mudah mengatur ulang indeks array untuk memulai dari 0 dan berurutan dalam array BARU, daripada mempertahankan indeks lama?

jel402
sumber
Kemungkinan duplikat php array_filter tanpa pelestarian kunci
Yep_It's_Me
Kecuali Anda benar-benar yakin bahwa Anda tidak memiliki nilai kosong / nol-ish / falsey dalam array Anda, saya harus mendorong Anda untuk tidak menggunakan array_filter()- Anda dapat membersihkan lebih dari yang Anda inginkan. Berikut adalah beberapa penjelasan dengan demo: stackoverflow.com/a/43657056/2943403
mickmackusa

Jawaban:

223

Jika Anda memanggil array_valuesarray Anda, itu akan diindeks ulang dari nol.

Daniel Vandersluis
sumber
Tautan tidak lagi berfungsi, gunakan php.net/manual/en/function.array-values.php sebagai gantinya. Saya tidak dapat memperbaruinya, karena saya perlu mengubah setidaknya 6 karakter.
Rasmus Hansen
37

Jika Anda menggunakan filter Array lakukan sebagai berikut

$NewArray = array_values(array_filter($OldArray));
pengguna2182143
sumber
3
Oh, waktu saya tersesat mencoba mencari tahu mengapa hasil dari json_encode sebuah array berbeda dari hasil dari json_encode sebuah array_filtered array ... terima kasih BANYAK ...
Jerther
13

Saya khawatir tentang berapa banyak programmer yang dengan polosnya menyalin / menempelkan array_values(array_filter())metode ke dalam kode mereka - Saya bertanya-tanya berapa banyak programmer yang tanpa disadari mengalami masalah karena keserakahan array_filter. Atau lebih buruk, berapa banyak orang yang tidak pernah menemukan bahwa fungsi tersebut menghapus terlalu banyak nilai dari larik ...

Saya akan menyajikan alternatif yang lebih baik untuk proses dua bagian pengupasan NULLelemen dari array dan mengindeks ulang kunci.

Namun, pertama-tama, sangat penting bagi saya untuk menekankan sifat serakah array_filter()dan bagaimana hal ini dapat menghentikan proyek Anda secara diam-diam. Berikut adalah array dengan nilai campuran di dalamnya yang akan mengekspos masalah:

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

Nilai nol akan dihapus terlepas dari huruf besar / kecil.

Tapi lihat apa yang tersisa dalam array ketika kita menggunakan array_values ​​() & array_filter () :

array_values(array_filter($array));

Array keluaran ($ array):

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

Sekarang lihat apa yang Anda dapatkan dengan metode saya yang menggunakan array_walk () & is_null () untuk menghasilkan array baru yang difilter:

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

Ini dapat ditulis dalam beberapa baris agar lebih mudah dibaca / dijelaskan:

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

Array keluaran ($ filter):

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

Dengan metode saya, Anda mendapatkan kunci yang diindeks ulang, semua nilai bukan nol, dan tidak ada nilai nol. Satu baris yang bersih, portabel, dan andal untuk semua kebutuhan penyaringan null array Anda. Ini sebuah demonstrasi .



Demikian pula, jika Anda ingin menghapus elemen kosong, salah, dan nol (mempertahankan nol), keempat metode ini akan berfungsi:

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

atau

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

atau

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

atau

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

Keluaran:

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

Terakhir, bagi siapa saja yang lebih menyukai sintaks konstruksi bahasa, Anda juga dapat memasukkan nilai yang memenuhi syarat ke dalam larik baru untuk menerbitkan indeks baru.

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

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

var_export($result);
mickmackusa.dll
sumber
2
Tidakkah hal-hal akan berperilaku persis seperti yang diharapkan jika Anda menulis array_values(array_filter($arr, function($el) {return $el !== '';}))? Itu sepertinya cara alami untuk melakukan apa yang diminta OP.
Casey
1
Iya. Maksud saya adalah bahwa pengembang harus menghindari dorongan untuk menggunakan perilaku default array_filter()kecuali jika pengetahuan mendalam mereka tentang data memungkinkan penyaringan serakah tanpa efek samping. (Perhatian lebih lanjut: empty()berperilaku dengan cara yang sama dan juga menyertakan larik kosong dalam keserakahannya.)
mickmackusa
2
Jawaban ini menjawab pertanyaan yang sama sekali berbeda, tidak terkait dengan yang asli dengan cara, bentuk, atau bentuk apa pun.
AnrDaemon
1
array_filter()berperilaku persis seperti yang Anda harapkan berdasarkan apa yang tertulis di manual: php.net/manual/en/function.array-filter.php "Jika tidak ada callback disediakan, semua entri array sama dengan FALSE (lihat mengonversi ke boolean ) akan dihapus. " Dan harus menjadi pengetahuan umum di antara programmer PHP bahwa 0, null, false, '' dan '0' semuanya bernilai false saat dipaksa ke boolean.
madsen
1
Masalahnya, kebanyakan orang tidak tahu apa yang diharapkan. Ya, saya lakukan, tetapi banyak yang tidak. Saya memposting jawaban ini untuk membantu orang yang tidak tahu.
mickmackusa
12

Penggunaan 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
Ed Mazur
sumber