Boş dizi öğelerini atlarken bir diziyi nasıl dağıtabilirim?


95

Perl join()boş dizi değerlerini yok sayar (atlar); PHP implode()görünmüyor.

Bir dizim olduğunu varsayalım:

$array = array('one', '', '', 'four', '', 'six');
implode('-', $array);

verim:

one---four--six

yerine (IMHO tercih edilir):

one-four-six

Aradığım davranışla ilgili başka yerleşik öğeler var mı? Yoksa özel bir jobbie mi olacak?


2
Perl'in davranışları hakkında yanılıyorsun. jointanımsız öğeleri atlamaz. Aslında, bir uyarı ile sonuçlanırlar. $a[0]="a"; $a[2]="c"; say join "-",@a;görüntüler Use of uninitialized value within @a in join or stringve a--c. join '-', grep !defined, ...Tanımlanmamış değerleri atlamak için kullanılabilir . grep !length,boş dizeler yapacak.
ikegami

Yanıtlar:


212

Şunları kullanabilirsiniz array_filter():

Hayır ise, geri arama beslenir, her girdi girişi için eşit FALSE(bakınız mantıksal dönüştürme kaldırılır).

implode('-', array_filter($array));

Açıktır ki , dizinizde 0(veya değerlendiren başka bir değer false) varsa ve onu korumak istiyorsanız bu işe yaramayacaktır . Ancak daha sonra kendi geri arama işlevinizi sağlayabilirsiniz.


5
Bu demek oluyor mu falseve 0onlar da atılır mı?
Ben

1
@maz: Evet, ancak her zaman kendi geri aramanızı sağlayabilirsiniz. empty, siz onu kullandıkça, btw olarak da muamele edecek 0ve (ve kaldıracaktır). falsefalse
Felix Kling

3
1, ama o bahsettiği gereken array_filter()varsayılan her filtrelerle false, nullboş dize ( '') ve 0.
Tadeck

1
@Tadeck: Evet, alıntıdaki bağlantıyı takip etmeniz yeterli. Daha da fazla değer şu şekilde kabul edilir false: boş dizi 0.0ve "0".
Felix Kling

@Felix: Bunu biliyordum - sadece PHP'ye yeni başlayanlar için vurgulamak istedim;) Neyse: teşekkür ederim
Tadeck

9

Sanırım yerleşik olduğunu düşünemezsiniz (çünkü işlev kullanıcı tanımlı bir işlevle çalışmaktadır), ancak her zaman array_filter kullanabilirsiniz .
Gibi bir şey:

function rempty ($var)
{
    return !($var == "" || $var == null);
}
$string = implode('-',array_filter($array, 'rempty'));

1
Kullanmak empty, geri arama yapılmaması ile aynı etkiye sahiptir. Düzenleme: Dönüş değerini reddetmeniz gerekir. Aksi takdirde yalnızca boş öğeler iade edilecektir;) (aslında emptydaha önce yaptığınız gibi kullanmak da yanlıştı)
Felix Kling

1
Evet, bu geriye doğru. Ama bana doğru fikri verdinimplode('-', array_filter($ary, create_function('$a', 'return $a!="";')));
Tom Auger

3

Filtrenizi nasıl uygulamanız gerektiği, yalnızca "boş" olarak gördüğünüze bağlıdır.

function my_filter($item)
{
    return !empty($item); // Will discard 0, 0.0, '0', '', NULL, array() of FALSE
    // Or...
    return !is_null($item); // Will only discard NULL
    // or...
    return $item != "" && $item !== NULL; // Discards empty strings and NULL
    // or... whatever test you feel like doing
}

function my_join($array)
{
    return implode('-',array_filter($array,"my_filter"));
} 

3

Kaldırmak için null, false, emptydize ancak korumak 0, vb kullanım fonk. ' strlen'

$arr = [null, false, "", 0, "0", "1", "2", "false"];
print_r(array_filter($arr, 'strlen'));

çıktı:

//Array ( [3] => 0 [4] => 0 [5] => 1 [6] => 2 [7] => false )

1

Bulabildiğim şeye dayanarak, bunun için yerleşik bir PHP kullanmanın gerçekten bir yolu olmadığını söyleyebilirim. Ama muhtemelen şu çizgide bir şeyler yapabilirsiniz:

function implode_skip_empty($glue,$arr) {
      $ret = "";
      $len = sizeof($arr);
      for($i=0;$i<$len;$i++) {
          $val = $arr[$i];    
          if($val == "") {
              continue;
          } else {
            $ret .= $arr.($i+1==$len)?"":$glue;
          }
      }
      return $ret;
}

1

Bunu dene:

$result = array();

foreach($array as $row) { 
   if ($row != '') {
   array_push($result, $row); 
   }
}

implode('-', $result);

1
$array = ["one", NULL, "two", NULL, "three"];
$string = implode("-", array_diff($array, [NULL]));
echo $string;

İadeler one-two-three


-1

array_fileter() burada kabul edilen yol gibi görünüyor ve muhtemelen hala en sağlam cevap tbh.

Bununla birlikte, "yapıştırıcı" karakterinin her bir dizi elemanının dizelerinde zaten bulunmadığını garanti edebiliyorsanız, aşağıdakiler de işe yarayacaktır (bu, çoğu pratik durumda verilecektir - aksi takdirde ayırt edemezsiniz) dizideki gerçek verilerden gelen yapıştırıcı):

$array = array('one', '', '', 'four', '', 'six');
$str   = implode('-', $array);
$str   = preg_replace ('/(-)+/', '\1', $str);

-3

Bunu dene:

if(isset($array))  $array = implode(",", (array)$array);

Uyarıları önlemek için isset () kullanmak isteyebilirsiniz.
user2775080

isset()Giriş dizisinin arrayorijinal gönderinin endişelerinden herhangi birini nasıl ele aldığından emin değilim ?
Tom Auger

1
Bu bir çözüm değil. (Dizi) 'ye çevrim, diziden boş öğeleri kaldırmaz.
mjwunderlich
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.