在跳过空数组项时如何爆破数组?


94

Perl join()忽略(跳过)空数组值;PHP的implode()似乎没有。

假设我有一个数组:

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

产量:

one---four--six

而不是(最好是恕我直言):

one-four-six

是否有其他任何具有我要寻找的行为的内置功能?还是将成为自定义工作人员?


2
您对Perl的行为是错误的。join不跳过未定义的元素。实际上,它们会导致警告。$a[0]="a"; $a[2]="c"; say join "-",@a;显示Use of uninitialized value within @a in join or stringa--c。可以join '-', grep !defined, ...用来跳过未定义的值。grep !length,将做空字符串。
ikegami

Answers:


210

您可以使用array_filter()

如果未提供回调,则将删除所有等于(请参阅转换为boolean)的输入项。FALSE

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

显然,如果您的数组中有0(或任何其他值为的值false)并且想要保留它,则此方法将不起作用。但是您可以提供自己的回调函数。


5
那是否意味着false0也被扔掉?

1
@maz:是的,但是您始终可以提供自己的回调。empty,在您使用它的同时,也将0false视为false(删除)。
菲利克斯·克林

3
+1,但它必须提到的是,array_filter()在默认情况下滤波器关每一个falsenull空字符串(“”)和0
塔德克

1
@Tadeck:是的,只需点击报价单中的链接即可。甚至可以将更多值视为false:空数组0.0"0"
菲利克斯·克林

@Felix:我知道这一点-只是想向PHP新手强调;)无论如何:谢谢
Tadeck 2011年

9

我想您不能考虑它是内置的(因为该函数正在使用用户定义的函数运行),但是您始终可以使用array_filter
就像是:

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

1
使用empty与完全不传递回调函数具有相同的效果。编辑:您必须否定返回值。否则,将仅返回空元素;)(实际上empty像以前一样使用也是错误的)
Felix Kling

1
是的,那是落后的。但是您给了我一个正确的主意implode('-', array_filter($ary, create_function('$a', 'return $a!="";')));
汤姆·奥格

3

过滤器的实现方式仅取决于您看到的“空”。

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

要删除nullfalseempty字符串但保留0等使用FUNC。' strlen'

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

将输出:

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

1

根据我的发现,我会说是有机会的,实际上没有任何方法可以使用内置的PHP。但是您可能可以按照以下方式做一些事情:

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

试试这个:

$result = array();

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

implode('-', $result);


-1

array_fileter() 似乎是这里公认的方法,并且可能仍然是最可靠的答案。

但是,如果您可以保证每个数组元素的字符串中都不存在“胶水”字符(以下情况在大多数实际情况下是给定的),则以下内容也将起作用:来自数组中实际数据的胶水):

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

-3

试试这个:

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

您可能要使用isset()来防止警告。
user2775080

我不确定如何isset()或将输入数组转换为array原始帖子的任何问题?
Tom Auger 2013年

1
这不是解决方案。强制转换为(数组)不会从数组中删除空项目。
mjwunderlich 2015年
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.