空の配列項目をスキップしながら配列を内破するにはどうすればよいですか?


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,空の文字列を実行します。
池上

回答:


210

使用できますarray_filter()

コールバックが指定されていない場合、等しい(ブール値への変換を参照)に等しい入力のすべてのエントリが削除されます。FALSE

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

配列に0(またはに評価されるその他の値false)があり、それを保持したい場合、明らかにこれは機能しません。ただし、独自のコールバック関数を提供できます。


5
それはを意味するでしょうかfalse、そして0また捨てられますか?
ベン

1
@maz:はい。ただし、いつでも独自のコールバックを提供できます。empty、使えば使うほど、また扱います0falseとしてfalseところで(と、それを削除します)。
Felix Kling、

3
+1、それがいることを、言及する必要があるarray_filter()デフォルトのフィルタによって、すべてのオフfalsenull空の文字列(「」)と0
Tadeck、

1
@Tadeck:はい、見積もりの​​リンクをクリックしてください。さらに値は以下のように考えられているfalse:空の配列、0.0および"0"
Felix Kling、

@Felix:私はそれを知っていました-PHPの初心者のためにそれを強調したかっただけです;)とにかく:ありがとう
Tadeck

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 2013

isset()入力配列をarray元の投稿の懸念事項に対処する方法またはキャストする方法がわかりませんか?
トムオージェ

1
これは解決策ではありません。(配列)にキャストしても、配列から空の項目は削除されません。
mjwunderlich 2015
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.