Boş dizi öğelerini kaldırma


783

Dizimdeki bazı öğeler, kullanıcının gönderdiklerine göre boş dizelerdir. Bu unsurları kaldırmam gerek. Bu bende var:

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

Ama işe yaramıyor. $linksArrayhala boş öğeleri var. Ayrıca empty()işlevi ile yapmayı denedim , ancak sonuç aynı.


1
Unset (...) foreach döngü tarafından oluşturulan değişken üzerinde çalışır, çünkü açıkça döngüden önce olduğu gibi orijinal dizisi üzerinde çalıştığı için yukarıdaki kod işe yaramaz bahsetmeye değer olduğunu düşündüm.
savedario

if (! empty ($ link)) {echo $ link; } bu benim için çalışıyor
Shiplu

U, referans alınmayan bir $ bağlantısını değiştiriyor! foreach kullan ($ linksArray $ key => $ link olarak) unset (linksArray [$ key])
TD_Nijboer

Yanıtlar:


1547

Bir dizi dizeyle uğraşırken, tüm bunları rahatça sizin için halledebilirsiniz array_filter():

print_r(array_filter($linksArray));

Unutmayın hiçbir geri arama verilir ise , dizinin tüm girişler için eşit FALSE(bkz boolean dönüştürme kaldırılacaktır). Dolayısıyla '0', tam dize olan öğeleri korumanız gerekiyorsa, özel bir geri aramaya ihtiyacınız olacaktır:

// 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_filterboş elemanları çıkarmalısınız. PHP'nin boş tanımınız tanımınızla tamamen aynı değilse, geri çağrı seçeneğini istenmeyen öğeleri dışarı atan anonim bir işlevle doldurabilirsiniz. Görünüşe göre anonim geri aramalar kullanmak için php 5.3 veya daha yenisine sahip olmalısınız. stackoverflow.com/questions/2412299/…
Buttle Butkus

76
dikkat dizi_dizini dizi dizinleri reindex yapmaz (for ifadesi süreç dizisi kullanılırken bir sorun oluşabilir). Yani hepsini array_values ​​işleviyle sarın.
Michal - wereda-net

8
Yanıt yanlış, çünkü falseöğeleri de kaldıracak . ( php.net/manual/tr/function.array-filter.php )
pliashkou

5
@ Deji filtrelemeden önce diziyi yazdırmayı denediniz mi? Ben aikinci kez ayarlamak sadece birincisini sıfırlar düşünüyorum .
Cullub

5
@Cranio: başka bir yorumda zaten yer alıyor. Bu yanlış, ama belki de değil , daha geniş daha da gereksinimleri. Bu, diğer insanların hala yararlı bulamayacağı anlamına gelmez; sonuçta, sahip olduğunuz tek şey dizinizdeki dizeler ise, bu cevap sadece boş olanları kaldıracaktır.
Martijn Pieters

169

array_filterBoş öğeleri kaldırmak için kullanabilirsiniz :

$emptyRemoved = array_filter($linksArray);

Dizinizde varsa (int) 0aşağıdakileri kullanabilirsiniz:

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

DÜZENLEME: Belki öğeleriniz kendi başına boş değildir, ancak bir veya daha fazla boşluk içerir ... Kullanmadan önce aşağıdakileri kullanabilirsinizarray_filter

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

10
Ben sadece BoltClock tarafından kabul edilen cevaba ekledim, sadece "0" sorunu önlemek ve sadece sıfır uzunlukta olanları kaldırmak için array_filter ($ foo, 'strlen') yapabilirdi.
AB Carroll

2
@nezZario: Dizinizde yalnızca scalaröğe olduğu varsayılarak evet. Aksi takdirde, bunu yapamazsınız.
Andrew Moore

2
Php için lambda kullanma> = 5.3function remove_empty($array) { return array_filter($array, function($value){return !empty($value) || $value === 0;}); }
Viral

1
array_map()o boş dizilerde boşluklar olduğu için büyü yaptım!
Prodigy

126

Bu konuda en popüler cevap kesinlikle YANLIŞ.

Aşağıdaki PHP betiğini göz önünde bulundurun:

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

Bu neden? Tek bir '0' karakteri içeren bir dize de boolean false olarak değerlendirildiğinden, boş bir dize olmasa da yine de filtrelenir. Bu bir hata olurdu.

Filtreleme işlevi olarak yerleşik strlen işlevinin iletilmesi, boş olmayan bir dize için sıfırdan farklı bir tamsayı ve boş bir dize için sıfırdan oluşan bir tamsayı döndürdüğünden çalışır. Sıfır olmayan tamsayılar, boole'ye dönüştürüldüğünde her zaman true değerini, sıfır tamsayılar ise boole'ye dönüştürüldüğünde her zaman false değerini değerlendirir.

Yani, mutlak, kesin, doğru cevap:

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

3
Kabul. Dizisi dize içerenler için bu kabul edilen cevap olmalıdır
mwieczorek

2
Upvoted. Diğerlerinden daha iyi bir cevap, ancak şu anda kabul edilen cevabın teknik olarak yanlış olduğuna dikkat edilmelidir, çünkü "boş" aslında PHP içinde özel bir anlama sahiptir. (Olarak nitelendirilebilecek bazı değerler "boş": 0, "", null)
rinogo

5
Yanlış değiller, hepsi bağlamla ilgili. Bazı durumlarda 0 değerini korumak önemli olabilir. Bu yüzden lütfen, senden başka herkesin yanlış olduğunu söyleme
Macr1408

6
Dizi başka bir dizi içeriyorsa bu strlen() expects parameter 1 to be string, array given
kesilir

İstediğiniz eylemleri gerçekleştirmek için bunun iyi bir yaklaşım da olduğunu söyleyebilirsiniz (başkalarına yanlış söylemek yerine).
MR_AMDEV

102
$linksArray = array_filter($linksArray);

"Hiçbir geri arama sağlanmazsa, FALSE öğesine eşit tüm giriş girdileri kaldırılır." - http://php.net/manual/en/function.array-filter.php


4
Sorunu Google’dan sonra da denedim. Ne yazık ki, benim için boş elemanlar bırakıyor.
Will

18
bu da '0'ı kaldıracak
OIS

2
@Will: Emin misin? Ayrıca boş dizeleri kaldırır, bunu başarıyla test ettim. Girdi değerleriniz boşluk içerebilir ve daha önce kesilmesi gerekir. Göre boolean dönüşüm kurallarının boş dize false değerlendirilir ve bu nedenle array_filter ile ayrılmıştır.
acme

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

strlen ayrıca yanlış kaldırır :(
justnorris

42

Sadece yapabilirsin

array_filter($array)

array_filter: "Hiçbir geri arama sağlanmazsa, FALSE öğesine eşit tüm giriş girdileri kaldırılır." Bu, NULL, 0, '0', '', FALSE, array () değerlerine sahip öğelerin de kaldırılacağı anlamına gelir.

Diğer seçenek

array_diff($array, array(''))

NULL, '' ve FALSE değerli öğeleri kaldıracak.

Bu yardımcı olur umarım :)

GÜNCELLEME

İşte bir örnek.

$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())

Sonuç olarak:

  • 0 veya '0', 0 ve '0'ı kaldıracak
  • NULL, FALSE veya '' NULL, FALSE ve '' öğelerini kaldıracak

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

4
Özlü, okunabilir ve güvenli bir çözüm falseve 0. Bunun kabul edilen cevapla aynı anda yayınlandığını düşünürsek (bu güvensiz ve yanlıştır), sadece kabul edilen yanıtın 649'una kıyasla 8 upvote'unuzun tek satırlık bir çözüm olduğunu varsayabilirim.
rybo111

@ rybo111 - muhtemelen, bu mantığı bir geri çağırmada kullanmak array_filter()bir foreach()döngüden daha temiz bir yaklaşım olurdu
Mark Baker

Belki daha hızlı, ancak çözümünüz en okunabilir olanıdır, bu önemlidir. Sizin çözüm gerektiren isteyenler için trim()tavsiye ederimif(is_string($link) && trim($link) === '')
rybo111

33

Dizinizden boş ("" boş dize) öğeleri kaldırmak için başka bir astar.

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

Not: Bu kod kasıtlı tutar null, 0ve falseöğeleri.


Veya önce dizi öğelerinizi kırpmak isteyebilirsiniz:

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

Not: Bu kod ayrıca kaldırır nullve falseöğeler.


3
Tam olarak ne gerek, ve bu da eski PHP ile uyumlu , teşekkürler! ;-)
Stano

1
@JohnK Yanlış. Bunu yapmak için, alzo zeroes ve diğer falsey değerlerini kaldırmak istemediğiniz sürece , kullanıcının geri arama için istediği gibi gereklidir.
Cranio

Oh ... bu kesinlikle çok güzel. Kabul edilen olmalı.
Henrik Petterson

20

Kısacası:

Bu benim önerilen kod:

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

Açıklama:

Kullanım array_filteriyi, ama yeterli değil, çünkü değerler gibi spaceve \n... dizide tutmak ve bu genellikle kötü olduğunu düşünüyor.

Bu yüzden karışım kullanmanızı öneririmarray_filterve array_map.

array_mapkırpmak içindir, array_filterboş değerleri kaldırmak strleniçindir, tutmak içindir0 değeri ve array_valuesgerekirse yeniden indekslemek içindir.

Örnekler:

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

Sonuçlar:

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"
}

Çevrimiçi Test:

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



12

En çok oy verilen cevap yanlıştır ya da OP sadece boş dizelerden bahsettiği için en azından tamamen doğru değildir. İşte kapsamlı bir açıklama:

Boş ne demektir?

Her şeyden önce, boş ne anlama geldiğine karar vermeliyiz . Filtrelemek istiyor musunuz:

  1. boş dizeler sadece ( "")?
  2. kesinlikle yanlış değerler? ( $element === false)
  3. Falsey değerleri? (yani 0, 0,0, "", "0", NULL, dizi () ...)
  4. PHP empty()işlevinin eşdeğeri ?

Değerleri nasıl filtrelersiniz

Yalnızca boş dizeleri filtrelemek için :

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

Yalnızca kesinlikle yanlış değerleri filtrelemek için bir geri arama işlevi kullanmalısınız :

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

Geri arama, bazıları hariç "falsey" değerlerini filtrelemek istediğiniz herhangi bir kombinasyon için de kullanışlıdır. (Örneğin, her filtre nullve falsesadece bırakarak vb 0):

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

Üçüncü ve dördüncü durum (sonunda bizim amacımız için) eşdeğerdir ve bunun için tek yapmanız gereken varsayılan değerdir:

$filtered = array_filter($originalArray);

2
Çıkarmak nullve falseancak 0'ı bırakmak istiyorsanız, strlengeri arama olarak php'nin yerleşik işlevini de kullanabilirsiniz .
Cullub

10

Ben (dize) 0 bir dizi değeri tutmak için bunu yapmak zorunda

$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

Çok boyutlu dizi için

$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

Bir diziden boş öğeleri kaldırmak için aşağıdaki komut dosyasını kullanıyorum

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

7

Sadece döngülere bir alternatif eklemek istiyorum ... aynı zamanda anahtarlardaki boşlukları ele almak ...

Benim durumumda, işlem tamamlandığında sıralı dizi tuşlarını tutmak istedim (sadece tek sayıları değil, baktığım şeydi. Sadece tek anahtarlara bakmak için kod ayarlamak bana kırılgan görünüyordu ve geleceğe dönük değildi.)

Daha böyle bir şey arıyordum: http://gotofritz.net/blog/howto/removing-empty-array-elements-php/

Array_filter ve array_slice kombinasyonu hile yapar.

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

Verimlilik veya kriterler hakkında hiçbir fikrim yok ama işe yarıyor.


Ben dizi_değerleri dizi_slice ile aynı sonucu olacağını düşünüyorum. Bu, kodu daha sonra okumak ve ne yaptığını anlamak açısından daha sezgisel görünüyor.
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>';
} 

çıktı

1: 5

2: 6



5

Sadece bir satır: Güncelleme (@suther sayesinde):

$array_without_empty_values = array_filter($array);

ikinci parametrenize gerek yok: $ clean_array = array_filter ($ dirty_array);
suther

4

array_filterboş değerleri kaldırmak için işlevi kullanın:

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

Boş değerlerle eşdeğer olmayan boş dizeleri kaldırmak istiyor .
Cranio

4

Boş dizi öğelerini kaldırma

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

işe yarıyor!


3

Yönteminize göre, bu öğeleri başka bir dizide yakalayabilir ve aşağıdaki gibi kullanabilirsiniz,

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

print_r($new_arr);

1

bunu deneyin ** ** Örnek

$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
bu nedir? çok alakalı başka cevaplar da var. Buraya ne ekliyorsunuz?
Félix Gagnon-Grenier

url'yi burada kontrol edin! / * boş dizi öğesini kaldır * /
Ashish pathak

1

Bence array_walk burada çok daha uygun

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

Çıktı:

Array
(
    [0] => name
    [2] => 342
    [3] => 0
    [4] => 0
)
  • Kullanıcı birden fazla boşluk eklese bile boş değerlerin kaldırıldığından emin olduk
  • Boş alanları da geçerli değerlerden kırptık

  • Son olarak, yalnızca (null), (Boolean False) ve ('') boş dizeler olarak kabul edilir

Gelince Falseo AFAIK kullanıcı boole değerlerini gönderin gelmediğinden dolayı kaldırmak için ok.


0

Bu tür şeylerle, ne istediğiniz ve ne istemediğiniz konusunda açık olmak çok daha iyidir.

Bir sonraki erkeğin, array_filter()geri arama olmadan davranışına sürprizlerle yakalanmamasına yardımcı olacaktır . Örneğin, bu soruya son verdim çünkü array_filter()kaldırılıp kaldırılmadığını unuttum NULL. Aşağıdaki çözümü yeni kullanabileceğim ve cevabımı alabileceğim zaman harcadım.

Ayrıca, mantık, array_filterherhangi bir geri arama geçirilmediğinde olduğu gibi, bir php işlevinin davranışının altında durmak zorunda kalmadan kodun başka bir dile kopyalanabilmesi anlamında dil tanılamasıdır .

Benim çözümümde, neler olduğuna dair bir bakışta açıktır. Bir şeyi saklamak için bir koşulu kaldırın veya ek değerlere filtre uygulamak için yeni bir koşul ekleyin.

array_filter()Sadece özel bir geri arama geçirdiğim için asıl kullanımını dikkate almayın - devam edip isterseniz kendi işlevine çıkarabilirsiniz. Sadece bir foreachilmek için şeker olarak kullanıyorum .

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

Bu yaklaşımın bir başka yararı da, filtreleme tahminlerini dizi başına tek bir değeri filtreleyen soyut bir işleve ayırabilmeniz ve oluşturulabilir bir çözüm oluşturabilmenizdir.

Bu örneğe ve çıktı için satır içi yorumlara bakın.

<?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]

Şimdi dinamik adlı bir işlev oluşturabilirsiniz filterer()kullanarak pipe()sizin için bu kısmen uygulanan işlevleri geçerli olacaktır.

<?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]
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.