Come posso implodere un array saltando gli elementi dell'array vuoto?


94

Il Perl join()ignora (salta) i valori di array vuoti; PHP implode()non sembra.

Supponiamo di avere un array:

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

rende:

one---four--six

invece di (IMHO il preferibile):

one-four-six

Qualche altro built-in con il comportamento che sto cercando? O sarà un jobbie personalizzato?


2
Ti sbagli sul comportamento di Perl. joinnon salta gli elementi indefiniti. In effetti, risultano in un avvertimento. $a[0]="a"; $a[2]="c"; say join "-",@a;visualizza Use of uninitialized value within @a in join or stringe a--c. Si può usare join '-', grep !defined, ...per saltare i valori indefiniti. grep !length,farà stringhe vuote.
ikegami

Risposte:


210

Puoi usare array_filter():

Se non viene fornito alcun callback , tutte le voci di input uguali a FALSE(vedere conversione in booleano ) verranno rimosse.

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

Ovviamente questo non funzionerà se hai 0(o qualsiasi altro valore che restituisce false) nel tuo array e vuoi mantenerlo. Ma poi puoi fornire la tua funzione di callback.


5
Vorrebbe dire questo falsee 0vengono anche buttati fuori?
Ben

1
@maz: Sì, ma puoi sempre fornire la tua richiamata. empty, mentre lo usi, tratterà anche 0e falsecome false(e lo rimuoverà) btw.
Felix Kling

3
+1, ma deve essere menzionato, che array_filter()dai filtri predefiniti fuori ogni false, null, stringa vuota ( '') e 0.
Tadeck

1
@Tadeck: Sì, segui il link nella citazione. Anche più valori sono considerati come false: array vuoto 0.0e "0".
Felix Kling

@Felix: lo sapevo - volevo solo sottolinearlo per le persone nuove in PHP;) Comunque: grazie
Tadeck

9

Suppongo che non puoi considerarlo integrato (perché la funzione è in esecuzione con una funzione definita dall'utente), ma potresti sempre usare array_filter .
Qualcosa di simile a:

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

1
L'uso emptyha lo stesso effetto di non passare affatto la richiamata. Modifica: devi negare il valore restituito. Altrimenti verranno restituiti solo gli elementi vuoti;) (anche l'uso in realtà emptycome hai fatto prima era sbagliato)
Felix Kling

1
Sì, è al contrario. Ma mi hai dato l'idea giustaimplode('-', array_filter($ary, create_function('$a', 'return $a!="";')));
Tom Auger

3

Il modo in cui implementare il filtro dipende solo da ciò che si vede come "vuoto".

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

Per rimuovere null, false, emptystringa ma preservare 0, ecc uso func. ' strlen'

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

produrrà:

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

1

In base a quello che posso trovare, direi che è probabile che non ci sia davvero alcun modo per utilizzare un PHP integrato per questo. Ma probabilmente potresti fare qualcosa sulla falsariga di questo:

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

Prova questo:

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

ritorna one-two-three


-1

array_fileter() sembra essere il modo accettato qui, ed è probabilmente ancora la risposta più robusta tbh.

Tuttavia, quanto segue funzionerà anche se puoi garantire che il carattere "colla" non esiste già nelle stringhe di ogni elemento dell'array (che sarebbe un dato nelle circostanze più pratiche - altrimenti non saresti in grado di distinguere la colla dai dati effettivi nell'array):

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

-3

Prova questo:

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

Potresti voler usare isset () per prevenire gli avvisi.
user2775080

Non sono sicuro di come isset()o il casting dell'array di input come arrayrisolve le preoccupazioni del post originale?
Tom Auger

1
Questa non è una soluzione. Il cast su (array) non rimuove gli elementi vuoti dall'array.
mjwunderlich
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.