¿Cómo puedo implosionar una matriz mientras omito elementos de matriz vacíos?

3 minutos de lectura

avatar de usuario
barrena tom

de Perl join() ignora (salta) valores de matriz vacíos; PHP implode() no parece.

Supongamos que tengo una matriz:

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

rendimientos:

one---four--six

en lugar de (en mi humilde opinión, el preferible):

one-four-six

¿Alguna otra función integrada con el comportamiento que estoy buscando? ¿O va a ser un trabajo personalizado?

  • Estás equivocado sobre el comportamiento de Perl. join no omite elementos no definidos. De hecho, resultan en una advertencia. $a[0]="a"; $a[2]="c"; say join "-",@a; muestra Use of uninitialized value within @a in join or string y a--c. uno puede usar join '-', grep !defined, ... para omitir valores no definidos. grep !length, hará cadenas vacías.

    – ikegami

    12 mayo 2011 a las 23:01


avatar de usuario
Félix Kling

Puedes usar array_filter():

Si no llamar de vuelta se suministra, todas las entradas de aporte igual a FALSE (ver convertir a booleano) será eliminado.

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

Obviamente esto no funcionará si tienes 0 (o cualquier otro valor que evalúe a false) en su matriz y desea mantenerlo. Pero luego puede proporcionar su propia función de devolución de llamada.

  • ¿Significaría eso que falsey 0 también se tiran?

    – Jesús

    12 mayo 2011 a las 22:54

  • @maz: Sí, pero siempre puede proporcionar su propia devolución de llamada. emptya medida que lo use, también tratará 0 y false como false (y eliminarlo) por cierto.

    – Félix Kling

    12 mayo 2011 a las 22:55


  • +1, pero hay que mencionar que array_filter() por defecto filtra cada false, nullcadena vacía (”) y 0.

    – Tadeck

    12 mayo 2011 a las 22:55

  • @Tadeck: Sí, solo siga el enlace en la cita. Incluso más valores se consideran como false: matriz vacía, 0.0 y "0".

    – Félix Kling

    12 mayo 2011 a las 22:58


  • @Felix: lo sabía, solo quería enfatizarlo para las personas nuevas en PHP;) De todos modos: gracias

    – Tadeck

    12 mayo 2011 a las 23:05

avatar de usuario
Cadena

Supongo que no puede considerarlo incorporado (porque la función se ejecuta con una función definida por el usuario), pero siempre puede usar matriz_filtro.
Algo como:

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

  • Usando empty tiene el mismo efecto que no pasar ninguna devolución de llamada. Editar: tienes que negar el valor de retorno. De lo contrario, solo se devolverán elementos vacíos;) (en realidad usando empty como hiciste antes también estuvo mal)

    – Félix Kling

    12 de mayo de 2011 a las 23:03


  • Sí, eso es al revés. Pero me diste la idea correcta implode('-', array_filter($ary, create_function('$a', 'return $a!="";')));

    – Tom Auger

    12 de mayo de 2011 a las 23:12

avatar de usuario
Ali Varli

Para eliminar null, false, empty cadena pero preservar 0etc. use la func. strlen

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

dará salida:

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

La forma en que debe implementar su filtro solo depende de lo que vea como “vacío”.

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

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

Devoluciones one-two-three

avatar de usuario
ozzmotik

Según lo que puedo encontrar, diría que lo más probable es que no haya ninguna forma de usar un PHP integrado para eso. Pero probablemente podrías hacer algo como esto:

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

avatar de usuario
jeremy

Prueba esto:

$result = array();

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

implode('-', $result);

¿Ha sido útil esta solución?