Hapus elemen array kosong


784

Beberapa elemen dalam array saya adalah string kosong berdasarkan apa yang telah dikirimkan pengguna. Saya perlu menghapus elemen-elemen itu. Aku punya ini:

foreach($linksArray as $link)
{
    if($link == '')
    {
        unset($link);
    }
}
print_r($linksArray);

Tapi itu tidak berhasil. $linksArraymasih memiliki elemen kosong. Saya juga sudah mencoba melakukannya dengan empty()fungsi, tetapi hasilnya sama.


1
Saya pikir perlu disebutkan bahwa kode di atas tidak berfungsi karena unset (...) beroperasi pada variabel yang dibuat oleh foreach loop, bukan array asli yang jelas tetap seperti sebelum loop.
Savedario

if (! empty ($ link)) {echo $ link; } ini bekerja untuk saya
Shiplu

Anda mengubah $ link yang tidak direferensikan! gunakan foreach ($ linksArray sebagai $ key => $ link) tidak disetel (linksArray [$ key])
TD_Nijboer

Jawaban:


1548

Saat Anda berurusan dengan serangkaian string, Anda bisa menggunakan array_filter(), yang dengan mudah menangani semua ini untuk Anda:

print_r(array_filter($linksArray));

Perlu diingat bahwa jika tidak ada panggilan balik yang diberikan , semua entri array sama dengan FALSE(lihat konversi ke boolean ) akan dihapus. Jadi, jika Anda perlu mempertahankan elemen yang merupakan string eksak '0', Anda akan membutuhkan panggilan balik khusus:

// PHP 7.4 and later
print_r(array_filter($linksArray, fn($value) => !is_null($value) && $value !== ''));

// PHP 5.3 and later
print_r(array_filter($linksArray, function($value) { return !is_null($value) && $value !== ''; }));

// PHP < 5.3
print_r(array_filter($linksArray, create_function('$value', 'return $value !== "";')));

16
array_filterharus menghapus elemen kosong. Dan jika definisi kosong PHP tidak sama dengan definisi Anda, maka Anda dapat mengisi opsi panggilan balik dengan fungsi anonim yang membuang elemen yang tidak diinginkan. Rupanya Anda harus memiliki php 5.3 atau yang lebih baru untuk menggunakan punggung panggilan anonim. stackoverflow.com/questions/2412299/…
Buttle Butkus

76
hati-hati array_filter tidak mengindeks indeks array (masalah dapat terjadi dalam menggunakan proses array dalam pernyataan). Jadi bungkus semuanya dengan fungsi array_values.
Michal - wereda-net

8
Jawabannya salah, karena akan menghilangkan falseelemen juga. ( php.net/manual/en/function.array-filter.php )
pliashkou

5
@ Dji apakah Anda sudah mencoba mencetak array itu sebelum memfilternya? Saya pikir pengaturan akedua kalinya hanya mengatur ulang yang pertama.
Cullub

5
@Cranio: yang sudah diliput oleh komentar lain. Ini tidak salah, tetapi mungkin lebih luas dari persyaratan Anda . Itu tidak berarti orang lain masih tidak merasa terbantu; setelah semua, jika semua yang Anda miliki adalah string dalam array Anda, jawaban ini hanya akan menghapus yang kosong.
Martijn Pieters

169

Anda dapat menggunakan array_filteruntuk menghapus elemen kosong:

$emptyRemoved = array_filter($linksArray);

Jika ada (int) 0dalam array Anda, Anda dapat menggunakan yang berikut:

$emptyRemoved = remove_empty($linksArray);

function remove_empty($array) {
  return array_filter($array, '_remove_empty_internal');
}

function _remove_empty_internal($value) {
  return !empty($value) || $value === 0;
}

EDIT: Mungkin elemen Anda tidak kosong tetapi hanya mengandung satu atau lebih spasi ... Anda dapat menggunakan yang berikut sebelum menggunakanarray_filter

$trimmedArray = array_map('trim', $linksArray);

10
Saya baru saja menambahkannya ke jawaban yang diterima oleh BoltClock, Anda cukup melakukan array_filter ($ foo, 'strlen') untuk menghindari masalah "0" dan hanya menghapus yang dengan panjang nol.
AB Carroll

2
@nezZario: Anggap Anda hanya memiliki scalaritem dalam array Anda, ya. Kalau tidak, Anda tidak bisa melakukan itu.
Andrew Moore

2
Menggunakan lambda untuk php> = 5.3function remove_empty($array) { return array_filter($array, function($value){return !empty($value) || $value === 0;}); }
Viral

1
array_map()lakukan keajaiban karena aku punya ruang di array kosong itu!
Prodigy

126

Jawaban paling populer tentang topik ini benar-benar TIDAK BENAR.

Pertimbangkan skrip PHP berikut:

<?php
$arr = array('1', '', '2', '3', '0');
// Incorrect:
print_r(array_filter($arr));
// Correct:
print_r(array_filter($arr, 'strlen'));

Kenapa ini? Karena string yang berisi karakter '0' tunggal juga mengevaluasi ke boolean false, jadi meskipun itu bukan string kosong, itu masih akan disaring. Itu akan menjadi bug.

Melewati fungsi strlen bawaan sebagai fungsi filter akan berfungsi, karena mengembalikan integer non-nol untuk string yang tidak kosong, dan integer nol untuk string kosong. Bilangan bulat nol selalu menilai true ketika dikonversi ke boolean, sedangkan bilangan bulat nol selalu bernilai false ketika dikonversi ke boolean.

Jadi, jawaban absolut, pasti, dan benar adalah:

$arr = array_filter($arr, 'strlen');

3
Sepakat. Ini harus menjadi jawaban yang diterima, bagi mereka yang
arraynya

2
Terpilih. Jawaban yang lebih baik daripada banyak yang lain, namun perlu dicatat bahwa jawaban yang saat ini diterima secara teknis tidak salah karena "kosong" memang memiliki arti khusus dalam PHP. (Beberapa nilai-nilai yang memenuhi syarat sebagai "kosong": 0, "", null)
rinogo

5
Mereka tidak salah, ini semua tentang konteks. Dalam beberapa kasus, mempertahankan nilai 0 bisa jadi penting. Jadi tolong, jangan katakan bahwa semua orang salah kecuali Anda
Macr1408

6
Ini rusak jika array berisi array lain:strlen() expects parameter 1 to be string, array given
hpaknia

Anda dapat mengatakan bahwa ini juga bisa menjadi pendekatan yang baik (alih-alih mengatakan yang lain salah) untuk mencapai tindakan yang diinginkan seseorang. Pada dasarnya tidak semua kasus serupa. Meskipun pendekatan ini bekerja untuk kasus saya.
MR_AMDEV

102
$linksArray = array_filter($linksArray);

"Jika tidak ada callback yang diberikan, semua entri input yang sama dengan FALSE akan dihapus." - http://php.net/manual/en/function.array-filter.php


4
Saya juga mencoba ini setelah Google'ing masalahnya. Sayangnya, itu meninggalkan elemen kosong bagi saya.
Will

18
ini juga akan menghapus '0'
OIS

2
@ Akan: apakah Anda yakin? Ini juga menghapus string kosong, saya berhasil menguji ini. Mungkin nilai input Anda mengandung spasi dan harus dipangkas sebelumnya. Menurut aturan konversi boolean string kosong dievaluasi menjadi false dan karenanya dihapus oleh array_filter.
acme

52
    $myarray = array_filter($myarray, 'strlen');  //removes null values but leaves "0"
    $myarray = array_filter($myarray);            //removes all null values

strlen juga menghapus false :(
justnorris

42

Anda bisa melakukannya

array_filter($array)

array_filter: "Jika tidak ada panggilan balik yang diberikan, semua entri input yang sama dengan FALSE akan dihapus." Ini berarti bahwa elemen dengan nilai NULL, 0, '0', '', FALSE, array () akan dihapus juga.

Pilihan lainnya adalah melakukan

array_diff($array, array(''))

yang akan menghapus elemen dengan nilai NULL, '' dan FALSE.

Semoga ini membantu :)

MEMPERBARUI

Berikut ini sebuah contoh.

$a = array(0, '0', NULL, FALSE, '', array());

var_dump(array_filter($a));
// array()

var_dump(array_diff($a, array(0))) // 0 / '0'
// array(NULL, FALSE, '', array());

var_dump(array_diff($a, array(NULL))) // NULL / FALSE / ''
// array(0, '0', array())

Untuk menyimpulkan:

  • 0 atau '0' akan menghapus 0 dan '0'
  • NULL, FALSE atau '' akan menghapus NULL, FALSE dan ''

36
foreach($linksArray as $key => $link) 
{ 
    if($link === '') 
    { 
        unset($linksArray[$key]); 
    } 
} 
print_r($linksArray); 

4
Solusi ringkas, mudah dibaca, dan aman yang tidak menghapus falsedan 0. Mengingat ini telah diposting pada menit yang sama dengan jawaban yang diterima (yang tidak aman dan salah), saya hanya dapat berasumsi 8 upvotes Anda dibandingkan dengan jawaban yang diterima 649 turun ke yang terakhir menjadi solusi satu baris.
rybo111

@ rybo111 - mungkin, meskipun menggunakan logika itu dalam panggilan balik untuk array_filter()menjadi pendekatan yang lebih bersih daripada foreach()loop
Mark Baker

Mungkin lebih cepat, tetapi solusi Anda adalah yang paling mudah dibaca, yang penting. Bagi mereka yang membutuhkan solusi Anda trim(), saya akan merekomendasikanif(is_string($link) && trim($link) === '')
rybo111

33

Satu liner lain untuk menghapus elemen kosong ("string kosong) dari array Anda.

$array = array_filter($array, function($a) {return $a !== "";});

Catatan: Kode ini sengaja disimpan null, 0dan falseelemen.


Atau mungkin Anda ingin memotong elemen array Anda terlebih dahulu:

$array = array_filter($array, function($a) {
    return trim($a) !== "";
});

Catatan: Kode ini juga menghapus nulldan falseelemen.


3
Tepat seperti yang saya butuhkan, dan ini juga kompatibel dengan PHP yang lebih lama , terima kasih! ;-)
Stano

1
@JohnK Salah. Untuk melakukan hal ini persis seperti whants pengguna untuk callback yang diperlukan, kecuali jika Anda ingin menghapus Alzo nol dan nilai-nilai falsey lainnya.
Cranio

Oh ... ini benar-benar indah. Seharusnya yang diterima.
Henrik Petterson

20

Pendeknya:

Ini adalah kode yang saya sarankan:

$myarray =  array_values(array_filter(array_map('trim', $myarray), 'strlen'));

Penjelasan:

Saya pikir penggunaan array_filteritu baik, tetapi tidak cukup, karena nilainya seperti spacedan \n, ... simpan dalam array dan ini biasanya buruk.

Jadi saya sarankan Anda menggunakan campuran array_filterdan array_map.

array_mapadalah untuk memotong, array_filteruntuk menghapus nilai kosong, strlenuntuk menyimpan 0nilai, dan array_valuesuntuk pengindeksan ulang jika Anda perlu.

Sampel:

$myarray = array("\r", "\n", "\r\n", "", " ", "0", "a");

// "\r", "\n", "\r\n", " ", "a"
$new1 = array_filter($myarray);

// "a"
$new2 = array_filter(array_map('trim', $myarray));

// "0", "a"
$new3 = array_filter(array_map('trim', $myarray), 'strlen');

// "0", "a" (reindex)
$new4 = array_values(array_filter(array_map('trim', $myarray), 'strlen'));

var_dump($new1, $new2, $new3, $new4);

Hasil:

array(5) {
  [0]=>
" string(1) "
  [1]=>
  string(1) "
"
  [2]=>
  string(2) "
"
  [4]=>
  string(1) " "
  [6]=>
  string(1) "a"
}
array(1) {
  [6]=>
  string(1) "a"
}
array(2) {
  [5]=>
  string(1) "0"
  [6]=>
  string(1) "a"
}
array(2) {
  [0]=>
  string(1) "0"
  [1]=>
  string(1) "a"
}

Tes Online:

http://phpio.net/s/5yg0


13

Jika Anda bekerja dengan array numerik dan perlu mengindeks ulang array setelah menghapus elemen kosong, gunakan fungsi array_values :

array_values(array_filter($array));

Juga lihat: array PHP reindex?


12

Jawaban yang paling banyak dipilih salah atau setidaknya tidak sepenuhnya benar karena OP hanya berbicara tentang string kosong. Berikut penjelasan lengkapnya:

Apa artinya kosong ?

Pertama-tama, kita harus sepakat tentang arti kosong . Maksud Anda menyaring:

  1. satu string kosong saja ( "")?
  2. nilai - nilai yang benar - benar salah ? ( $element === false)
  3. yang falsey nilai-nilai? (mis. 0, 0,0, "", "0", NULL, array () ...)
  4. setara dengan empty()fungsi PHP ?

Bagaimana Anda memfilter nilai

Untuk memfilter hanya string kosong :

$filtered = array_diff($originalArray, array(""));

Untuk hanya memfilter nilai yang sepenuhnya salah , Anda harus menggunakan fungsi callback :

$filtered = array_diff($originalArray, 'myCallback');
function myCallback($var) {
    return $var === false;
}

Panggilan balik ini juga berguna untuk kombinasi apa pun di mana Anda ingin memfilter nilai "falsey", kecuali beberapa. (Misalnya, filter setiap nulldan false, dll, hanya menyisakan 0):

$filtered = array_filter($originalArray, 'myCallback');
function myCallback($var) {
    return ($var === 0 || $var === '0');
}

Kasus ketiga dan keempat setara (untuk tujuan kami pada akhirnya), dan untuk itu yang harus Anda gunakan adalah default:

$filtered = array_filter($originalArray);

2
Jika Anda ingin mengambil nulldan false, tetapi meninggalkan 0, Anda juga dapat menggunakan strlenfungsi built-in php sebagai panggilan balik Anda.
Cullub

10

Saya harus melakukan ini untuk menjaga nilai array (string) 0

$url = array_filter($data, function ($value) {
  return (!empty($value) || $value === 0 || $value==='0');
});

9
$a = array(1, '', '', '', 2, '', 3, 4);
$b = array_values(array_filter($a));

print_r($b)

9

Untuk array multidimensi

$data = array_map('array_filter', $data);
$data = array_filter($data);

9
$out_array = array_filter($input_array, function($item) 
{ 
    return !empty($item['key_of_array_to_check_whether_it_is_empty']); 
}
);

9
function trim_array($Array)
{
    foreach ($Array as $value) {
        if(trim($value) === '') {
            $index = array_search($value, $Array);
            unset($Array[$index]);
        }
    }
    return $Array;
}

7

Saya menggunakan skrip berikut untuk menghapus elemen kosong dari array

for ($i=0; $i<$count($Array); $i++)
  {
    if (empty($Array[$i])) unset($Array[$i]);
  }

7

Hanya ingin berkontribusi alternatif untuk loop ... juga mengatasi celah kunci ...

Dalam kasus saya, saya ingin menyimpan kunci array berurutan ketika operasi selesai (bukan hanya angka ganjil, yang saya tatap. Menyiapkan kode untuk mencari kunci aneh tampak rapuh bagi saya dan tidak ramah untuk masa depan.)

Saya mencari sesuatu yang lebih seperti ini: http://gotofritz.net/blog/howto/removing-empty-array-elements-php/

Kombinasi dari array_filter dan array_slice berhasil.

$example = array_filter($example); $example = array_slice($example,0);

Tidak tahu efisiensi atau tolok ukur tetapi itu berhasil.


Saya pikir array_values ​​akan memiliki hasil yang sama dengan array_slice. Tampaknya lebih intuitif dalam hal membaca kode nanti dan memahami apa yang dilakukannya.
arlomedia

6
$my = ("0"=>" ","1"=>"5","2"=>"6","3"=>" ");   

foreach ($my as $key => $value) {
    if (is_null($value)) unset($my[$key]);
}

foreach ($my as $key => $value) {
    echo   $key . ':' . $value . '<br>';
} 

keluaran

1: 5

2: 6



5

Hanya satu baris: Perbarui (terima kasih kepada @suther):

$array_without_empty_values = array_filter($array);

tidak memerlukan parameter kedua Anda: $ clean_array = array_filter ($ dirty_array);
suther

4

gunakan array_filterfungsi untuk menghapus nilai kosong:

$linksArray = array_filter($linksArray);
print_r($linksArray);

Dia ingin menghapus string kosong , yang tidak setara dengan nilai kosong.
Cranio

4

Hapus elemen array kosong

function removeEmptyElements(&$element)
{
    if (is_array($element)) {
        if ($key = key($element)) {
            $element[$key] = array_filter($element);
        }

        if (count($element) != count($element, COUNT_RECURSIVE)) {
            $element = array_filter(current($element), __FUNCTION__);
        }

        return $element;
    } else {
        return empty($element) ? false : $element;
    }
}

$data = array(
    'horarios' => array(),
    'grupos' => array(
        '1A' => array(
            'Juan' => array(
                'calificaciones' => array(
                    'Matematicas' => 8,
                    'Español' => 5,
                    'Ingles' => 9,
                ),
                'asistencias' => array(
                    'enero' => 20,
                    'febrero' => 10,
                    'marzo' => '',
                )
            ),
            'Damian' => array(
                'calificaciones' => array(
                    'Matematicas' => 10,
                    'Español' => '',
                    'Ingles' => 9,
                ),
                'asistencias' => array(
                    'enero' => 20,
                    'febrero' => '',
                    'marzo' => 5,
                )
            ),
        ),
        '1B' => array(
            'Mariana' => array(
                'calificaciones' => array(
                    'Matematicas' => null,
                    'Español' => 7,
                    'Ingles' => 9,
                ),
                'asistencias' => array(
                    'enero' => null,
                    'febrero' => 5,
                    'marzo' => 5,
                )
            ),
        ),
    )
);

$data = array_filter($data, 'removeEmptyElements');
var_dump($data);

berhasil!


3

Sesuai metode Anda, Anda bisa menangkap elemen-elemen itu di array lain dan menggunakannya seperti berikut,

foreach($linksArray as $link){
   if(!empty($link)){
      $new_arr[] = $link
   }
}

print_r($new_arr);

1

coba ini ** ** Contoh

$or = array(
        'PersonalInformation.first_name' => $this->request->data['User']['first_name'],
        'PersonalInformation.last_name' => $this->request->data['User']['last_name'],
        'PersonalInformation.primary_phone' => $this->request->data['User']['primary_phone'],
        'PersonalInformation.dob' => $this->request->data['User']['dob'],
        'User.email' => $this->request->data['User']['email'],
    );



 $or = array_filter($or);

    $condition = array(
        'User.role' => array('U', 'P'),
        'User.user_status' => array('active', 'lead', 'inactive'),
        'OR' => $or
    );

1
apa ini? ada banyak jawaban lain yang sangat relevan. Apa yang kamu tambahkan di sini?
Félix Gagnon-Grenier

lihat url apa pertanyaannya di sini !! / * hapus elemen array kosong * /
Ashish pathak

1

Saya pikir array_walk jauh lebih cocok di sini

$linksArray = array('name', '        ', '  342', '0', 0.0, null, '', false);

array_walk($linksArray, function(&$v, $k) use (&$linksArray){
    $v = trim($v);
    if ($v == '')
        unset($linksArray[$k]);
});
print_r($linksArray);

Keluaran:

Array
(
    [0] => name
    [2] => 342
    [3] => 0
    [4] => 0
)
  • Kami memastikan bahwa nilai kosong dihapus bahkan jika pengguna menambahkan lebih dari satu ruang
  • Kami juga memangkas ruang kosong dari nilai yang valid

  • Akhirnya, hanya (null), (Boolean False) dan ('') akan dianggap sebagai string kosong

Adapun Falsetidak masalah untuk menghapusnya, karena AFAIK pengguna tidak dapat mengirimkan nilai boolean.


0

Dengan hal-hal semacam ini, jauh lebih baik untuk bersikap eksplisit tentang apa yang Anda inginkan dan tidak inginkan.

Ini akan membantu orang berikutnya untuk tidak terkejut dengan perilaku array_filter()tanpa panggilan balik. Misalnya, saya berakhir dengan pertanyaan ini karena saya lupa apakah array_filter()menghapus NULLatau tidak. Saya membuang-buang waktu ketika saya bisa saja menggunakan solusi di bawah ini dan mendapatkan jawaban saya.

Juga, logikanya adalah bahasa angnostik dalam arti bahwa kode dapat disalin ke bahasa lain tanpa harus memahami perilaku fungsi php seperti array_filterketika tidak ada panggilan balik yang dilewatkan.

Dalam solusi saya, jelas sekali apa yang terjadi. Hapus persyaratan untuk menyimpan sesuatu atau menambahkan kondisi baru untuk memfilter nilai tambahan.

Abaikan penggunaan sebenarnya array_filter()karena saya baru saja menyampaikannya sebagai panggilan balik kustom - Anda bisa melanjutkan dan mengekstraknya ke fungsinya sendiri jika Anda mau. Saya hanya menggunakannya sebagai gula untuk satu foreachputaran.

<?php

$xs = [0, 1, 2, 3, "0", "", false, null];

$xs = array_filter($xs, function($x) {
    if ($x === null) { return false; }
    if ($x === false) { return false; }
    if ($x === "") { return false; }
    if ($x === "0") { return false; }
    return true;
});

$xs = array_values($xs); // reindex array   

echo "<pre>";
var_export($xs);

Manfaat lain dari pendekatan ini adalah Anda dapat memecah predikat pemfilteran menjadi fungsi abstrak yang memfilter nilai tunggal per larik dan membangun solusi komposabel.

Lihat contoh ini dan komentar sebaris untuk hasilnya.

<?php

/**
 * @param string $valueToFilter
 *
 * @return \Closure A function that expects a 1d array and returns an array
 *                  filtered of values matching $valueToFilter.
 */
function filterValue($valueToFilter)
{
    return function($xs) use ($valueToFilter) {
        return array_filter($xs, function($x) use ($valueToFilter) {
            return $x !== $valueToFilter;
        });
    };
}

// partially applied functions that each expect a 1d array of values
$filterNull = filterValue(null);
$filterFalse = filterValue(false);
$filterZeroString = filterValue("0");
$filterEmptyString = filterValue("");

$xs = [0, 1, 2, 3, null, false, "0", ""];

$xs = $filterNull($xs);        //=> [0, 1, 2, 3, false, "0", ""]
$xs = $filterFalse($xs);       //=> [0, 1, 2, 3, "0", ""]
$xs = $filterZeroString($xs);  //=> [0, 1, 2, 3, ""]
$xs = $filterEmptyString($xs); //=> [0, 1, 2, 3]

echo "<pre>";
var_export($xs); //=> [0, 1, 2, 3]

Sekarang Anda dapat secara dinamis membuat fungsi yang disebut filterer()using pipe()yang akan menerapkan fungsi-fungsi yang diterapkan sebagian ini untuk Anda.

<?php

/**
 * Supply between 1..n functions each with an arity of 1 (that is, accepts
 * one and only one argument). Versions prior to php 5.6 do not have the
 * variadic operator `...` and as such require the use of `func_get_args()` to
 * obtain the comma-delimited list of expressions provided via the argument
 * list on function call.
 *
 * Example - Call the function `pipe()` like:
 *
 *   pipe ($addOne, $multiplyByTwo);
 *
 * @return closure
 */
function pipe()
{
    $functions = func_get_args(); // an array of callable functions [$addOne, $multiplyByTwo]
    return function ($initialAccumulator) use ($functions) { // return a function with an arity of 1
        return array_reduce( // chain the supplied `$arg` value through each function in the list of functions
            $functions, // an array of functions to reduce over the supplied `$arg` value
            function ($accumulator, $currFn) { // the reducer (a reducing function)
                return $currFn($accumulator);
            },
            $initialAccumulator
        );
    };
}

/**
 * @param string $valueToFilter
 *
 * @return \Closure A function that expects a 1d array and returns an array
 *                  filtered of values matching $valueToFilter.
 */
function filterValue($valueToFilter)
{
    return function($xs) use ($valueToFilter) {
        return array_filter($xs, function($x) use ($valueToFilter) {
            return $x !== $valueToFilter;
        });
    };
}

$filterer = pipe(
    filterValue(null),
    filterValue(false),
    filterValue("0"),
    filterValue("")
);

$xs = [0, 1, 2, 3, null, false, "0", ""];
$xs = $filterer($xs);

echo "<pre>";
var_export($xs); //=> [0, 1, 2, 3]
Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.