空の配列要素を削除する


783

私の配列の一部の要素は、ユーザーが送信したものに基づく空の文字列です。それらの要素を削除する必要があります。私はこれを持っています:

foreach($linksArray as $link)
{
    if($link == '')
    {
        unset($link);
    }
}
print_r($linksArray);

しかし、それは機能しません。$linksArrayまだ空の要素があります。私もempty()関数でそれをやってみましたが、結果は同じです。


1
unset(...)はforeachループによって作成された変数を操作するため、上記のコードは機能しないことを言及する価値があると思いました。ループの前の状態のままである元の配列ではありません。
savedario

if(!empty($ link)){echo $ link; }これでうまく
いき

Uは、参照されていない$ linkを変更しています!foreach($ linksArray as $ key => $ link)unset(linksArray [$ key])
TD_Nijboer

回答:


1548

文字列の配列を扱っているので、単純にを使用できarray_filter()ます。

print_r(array_filter($linksArray));

コールバックが指定されていない場合、に等しい配列のすべてのエントリFALSEブール値への変換を参照)が削除されることに注意してください。つまり、厳密な文字列'0'である要素を保持する必要がある場合は、カスタムコールバックが必要になります。

// PHP 7.4 and later
print_r(array_filter($linksArray, fn($value) => !is_null($value) && $value !== ''));

// PHP 5.3 and later
print_r(array_filter($linksArray, function($value) { return !is_null($value) && $value !== ''; }));

// PHP < 5.3
print_r(array_filter($linksArray, create_function('$value', 'return $value !== "";')));

16
array_filter空の要素を削除する必要があります。また、PHPのemptyの定義が定義とまったく異なる場合は、不要な要素をスローする匿名関数をコールバックオプションに入力できます。どうやら匿名のコールバックを使用するには、php 5.3以降が必要です。stackoverflow.com/questions/2412299/...
バトルバトカス

76
array_filterが配列インデックスのインデックスを再作成しないことに注意してください(forステートメントでforステートメントを使用するときに問題が発生する可能性があります)。したがって、すべてをarray_values関数でラップします。
ミハル-ワレダネット2014年

8
false要素も削除されるため、答えは不正解です。(php.net/manual/en/function.array-filter.php
pliashkou

5
@Dejiフィルタリングする前にその配列を印刷してみましたか?a2回目を設定すると、1回目がリセットされるだけだと思います。
Cullub 2016年

5
@Cranio:これはすでに別のコメントでカバーされています。それは間違っていないが、おそらく広いよりも、あなたの要件。これは、他の人がまだ役に立たないというわけではありません。結局のところ、すべてが配列内の文字列である場合、この答えは空のものだけを削除します。
Martijn Pieters

169

を使用array_filterして空の要素を削除できます。

$emptyRemoved = array_filter($linksArray);

あなたが持っている場合は(int) 0、あなたの配列には、次のように使用することができます:

$emptyRemoved = remove_empty($linksArray);

function remove_empty($array) {
  return array_filter($array, '_remove_empty_internal');
}

function _remove_empty_internal($value) {
  return !empty($value) || $value === 0;
}

編集:たぶんあなたの要素自体は空ではありませんが1つ以上のスペースが含まれています...使用する前に以下を使用できますarray_filter

$trimmedArray = array_map('trim', $linksArray);

10
BoltClockで承認された回答に追加したところです。array_filter($ foo、 'strlen')を実行して、「0」の問題を回避し、長さが0の問題のみを削除できます。
ABキャロル

2
@nezZario:scalar配列に項目のみがあると想定します。そうでなければ、それはできません。
Andrew Moore

2
PHPでラムダを使用する> = 5.3function remove_empty($array) { return array_filter($array, function($value){return !empty($value) || $value === 0;}); }
Viral

1
array_map()私はそれらの空の配列にスペースがあった魔法のcosをしました!
プロディジー

126

このトピックで最も人気のある答えは完全に誤りです。

次のPHPスクリプトを考えてみます。

<?php
$arr = array('1', '', '2', '3', '0');
// Incorrect:
print_r(array_filter($arr));
// Correct:
print_r(array_filter($arr, 'strlen'));

どうしてこれなの?単一の「0」文字を含む文字列もブール値のfalseに評価されるため、空の文字列でなくても、フィルターされます。それはバグでしょう。

組み込みのstrlen関数をフィルタリング関数として渡すと機能します。空でない文字列の場合はゼロ以外の整数が返され、空の文字列の場合はゼロの整数が返されるためです。ゼロ以外の整数はブール値に変換されると常にtrueと評価され、ブール値に変換されるとゼロ整数は常にfalseと評価されます。

だから、絶対的で決定的な正しい答えは:

$arr = array_filter($arr, 'strlen');

3
同意した。配列に文字列が含まれる場合、これは受け入れられる答えです
mwieczorek

2
賛成。他の多くの回答よりも良い回答ですが、「空」は実際にはPHP内で特別な意味があるため、現在受け入れられている回答は技術的に正しくないことに注意してください。(「空」としての資格をいくつかの値は:0""null
rinogo

5
それらは不正確ではなく、それはすべてコンテキストに関するものです。場合によっては、値0を維持することが重要になることがあります。だから、その誰もがあなたを除いて間違っているなんて言わないでください
Macr1408

6
この休憩配列は別の配列が含まれている場合:strlen() expects parameter 1 to be string, array given
hpaknia

これは、他の人が間違っていると言うのではなく、望ましいアクションを達成するための良いアプローチであるとも言えます。基本的に、すべてのケースが類似しているわけではありません。
MR_AMDEV

102
$linksArray = array_filter($linksArray);

「コールバックが提供されない場合、FALSEに等しい入力のすべてのエントリが削除されます。」- http://php.net/manual/en/function.array-filter.php


4
私はグーグルの問題の後でこれも試しました。残念ながら、それは私にとっては空白の要素のままです。
ウィル

18
これにより、「0」も削除されます
OIS

2
@Will:よろしいですか?空の文字列も削除されます。私はこれを正常にテストしました。入力値にスペースが含まれている可能性があるため、事前に削除する必要があります。よるブール変換規則空の文字列が偽に評価され、従ってarray_filterにより除去しました。
acme


42

あなたはただすることができます

array_filter($array)

array_filter: "コールバックが提供されない場合、FALSEに等しい入力のすべてのエントリが削除されます。" つまり、値がNULL、0、 '0'、 ''、FALSE、array()の要素も削除されます。

他のオプションはやっています

array_diff($array, array(''))

NULL、 ''、FALSEの値を持つ要素を削除します。

お役に立てれば :)

更新

ここに例があります。

$a = array(0, '0', NULL, FALSE, '', array());

var_dump(array_filter($a));
// array()

var_dump(array_diff($a, array(0))) // 0 / '0'
// array(NULL, FALSE, '', array());

var_dump(array_diff($a, array(NULL))) // NULL / FALSE / ''
// array(0, '0', array())

総括する:

  • 0または '0'は0と '0'を削除します
  • NULL、FALSEまたは ''は、NULL、FALSEおよび ''を削除します

36
foreach($linksArray as $key => $link) 
{ 
    if($link === '') 
    { 
        unset($linksArray[$key]); 
    } 
} 
print_r($linksArray); 

4
簡潔で、削除されません読めるし、安全なソリューションfalse0。これが承認された回答と同じ分に投稿されことを考えると(安全でなく、正しくありません)、承認された回答の649に比べて8つの賛成票のみが1行の解決策であると推測できます。
rybo111

@ rybo111-おそらく、そのロジックをコールバックで使用するarray_filter()と、foreach()ループよりもクリーンなアプローチになります
Mark Ba​​ker

多分もっと速いですが、あなたの解決策は最も読みやすいです、それは重要です。必要なソリューションを使用している人trim()には、私がお勧めしますif(is_string($link) && trim($link) === '')
rybo111

33

空の( ""空の文字列)要素を配列から削除するもう1つのライナー。

$array = array_filter($array, function($a) {return $a !== "";});

注:このコードは意図的null0false要素を保持しています。


または、最初に配列要素をトリミングすることもできます。

$array = array_filter($array, function($a) {
    return trim($a) !== "";
});

注:このコードは要素も削除nullfalseます。


3
まさに私が必要としていたものであり、これは古いPHPとも互換性があります。;-)
Stano 2013

1
@JohnK間違い。これを行うに、アルゾゼロやその他の誤った値を削除したくない場合を除き、ユーザーがコールバック必要としているのとまったく同じようにします。
Cranio

ああ...これは本当に素敵です。受け入れられるものでなければなりません。
Henrik Petterson 2016年

20

要するに:

これは私の推奨コードです:

$myarray =  array_values(array_filter(array_map('trim', $myarray), 'strlen'));

説明:

array_filter値はspaceand \n、...のようになっているため、使用は良いと思いますが、十分ではありません。配列に保持してください。これは通常悪いことです。

だから私は、あなたが混合物を使用することをお勧めarray_filterしてarray_map

array_mapはトリミングarray_filter用、空の値の削除strlen用、保持0値用、array_values必要に応じて再インデックス用です。

サンプル:

$myarray = array("\r", "\n", "\r\n", "", " ", "0", "a");

// "\r", "\n", "\r\n", " ", "a"
$new1 = array_filter($myarray);

// "a"
$new2 = array_filter(array_map('trim', $myarray));

// "0", "a"
$new3 = array_filter(array_map('trim', $myarray), 'strlen');

// "0", "a" (reindex)
$new4 = array_values(array_filter(array_map('trim', $myarray), 'strlen'));

var_dump($new1, $new2, $new3, $new4);

結果:

array(5) {
  [0]=>
" string(1) "
  [1]=>
  string(1) "
"
  [2]=>
  string(2) "
"
  [4]=>
  string(1) " "
  [6]=>
  string(1) "a"
}
array(1) {
  [6]=>
  string(1) "a"
}
array(2) {
  [5]=>
  string(1) "0"
  [6]=>
  string(1) "a"
}
array(2) {
  [0]=>
  string(1) "0"
  [1]=>
  string(1) "a"
}

オンラインテスト:

http://phpio.net/s/5yg0



12

OPが空の文字列のみについて話しているため、最も投票された答えは間違っているか、少なくとも完全に真ではありません。これは完全な説明です:

とはどういう意味ですか?

まず、が何を意味するかについて合意する必要があります。除外するつもりですか:

  1. 空の文字列のみ(「」)?
  2. 厳密に偽の値?($element === false
  3. falseyの値は?(つまり、0、0.0、 ""、 "0"、NULL、array()...)
  4. PHPのempty()関数と同等ですか?

値をどのように除外しますか

フィルタリングするには、空の文字列のみを

$filtered = array_diff($originalArray, array(""));

厳密に偽の値のみを除外するには、コールバック関数を使用する必要があります

$filtered = array_diff($originalArray, 'myCallback');
function myCallback($var) {
    return $var === false;
}

コールバックは、一部を除いて、「誤った」値を除外する任意の組み合わせにも役立ちます。(たとえば、すべてのnullとをフィルタリングしfalse、だけを残します0):

$filtered = array_filter($originalArray, 'myCallback');
function myCallback($var) {
    return ($var === 0 || $var === '0');
}

3番目と4番目のケースは(ついに私たちの目的で)同等であり、そのために使用する必要があるのはデフォルトのみです。

$filtered = array_filter($originalArray);

2
nulland を取り出したいfalseが0のままにしたい場合は、phpの組み込みstrlen関数をコールバックとして使用することもできます。
Cullub 2016年

10

(string)0の配列値を維持するためにこれを行わなければなりませんでした

$url = array_filter($data, function ($value) {
  return (!empty($value) || $value === 0 || $value==='0');
});

9
$a = array(1, '', '', '', 2, '', 3, 4);
$b = array_values(array_filter($a));

print_r($b)

9

多次元配列の場合

$data = array_map('array_filter', $data);
$data = array_filter($data);


9
function trim_array($Array)
{
    foreach ($Array as $value) {
        if(trim($value) === '') {
            $index = array_search($value, $Array);
            unset($Array[$index]);
        }
    }
    return $Array;
}

7

次のスクリプトを使用して、配列から空の要素を削除します

for ($i=0; $i<$count($Array); $i++)
  {
    if (empty($Array[$i])) unset($Array[$i]);
  }

7

ループの代わりに貢献したいだけです...キーのギャップにも対処します...

私の場合、操作が完了したときにシーケンシャル配列キーを保持したいと思いました(奇数だけではなく、これを見つめていました。奇数キーだけを検索するようにコードを設定すると、私にとって壊れやすく、将来的に使いにくいように見えました)。

私はもっ​​とこのようなものを探していました:http : //gotofritz.net/blog/howto/removing-empty-array-elements-php/

array_filterとarray_sliceを組み合わせるとうまくいきます。

$example = array_filter($example); $example = array_slice($example,0);

効率やベンチマークについてはわかりませんが、機能します。


array_valuesはarray_sliceと同じ結果になると思います。後でコードを読んでそれが何をしているのかを理解するという点で、それはより直感的に思えます。
arlomedia 2015年

6
$my = ("0"=>" ","1"=>"5","2"=>"6","3"=>" ");   

foreach ($my as $key => $value) {
    if (is_null($value)) unset($my[$key]);
}

foreach ($my as $key => $value) {
    echo   $key . ':' . $value . '<br>';
} 

出力

1:5

2:6



5

たった1行:更新(@sutherに感謝):

$array_without_empty_values = array_filter($array);

2番目のパラメーターは必要ありません。$ clean_array = array_filter($ dirty_array);
2014

4

array_filter関数を使用して空の値を削除します。

$linksArray = array_filter($linksArray);
print_r($linksArray);

彼は空の文字列を削除したいと考えています。これは空の値と同等ではありません。
Cranio

4

空の配列要素を削除する

function removeEmptyElements(&$element)
{
    if (is_array($element)) {
        if ($key = key($element)) {
            $element[$key] = array_filter($element);
        }

        if (count($element) != count($element, COUNT_RECURSIVE)) {
            $element = array_filter(current($element), __FUNCTION__);
        }

        return $element;
    } else {
        return empty($element) ? false : $element;
    }
}

$data = array(
    'horarios' => array(),
    'grupos' => array(
        '1A' => array(
            'Juan' => array(
                'calificaciones' => array(
                    'Matematicas' => 8,
                    'Español' => 5,
                    'Ingles' => 9,
                ),
                'asistencias' => array(
                    'enero' => 20,
                    'febrero' => 10,
                    'marzo' => '',
                )
            ),
            'Damian' => array(
                'calificaciones' => array(
                    'Matematicas' => 10,
                    'Español' => '',
                    'Ingles' => 9,
                ),
                'asistencias' => array(
                    'enero' => 20,
                    'febrero' => '',
                    'marzo' => 5,
                )
            ),
        ),
        '1B' => array(
            'Mariana' => array(
                'calificaciones' => array(
                    'Matematicas' => null,
                    'Español' => 7,
                    'Ingles' => 9,
                ),
                'asistencias' => array(
                    'enero' => null,
                    'febrero' => 5,
                    'marzo' => 5,
                )
            ),
        ),
    )
);

$data = array_filter($data, 'removeEmptyElements');
var_dump($data);

できます!


3

あなたのメソッドに従って、別の配列でそれらの要素をキャッチし、それを次のように使用することができます、

foreach($linksArray as $link){
   if(!empty($link)){
      $new_arr[] = $link
   }
}

print_r($new_arr);

1

これを試してください** **例

$or = array(
        'PersonalInformation.first_name' => $this->request->data['User']['first_name'],
        'PersonalInformation.last_name' => $this->request->data['User']['last_name'],
        'PersonalInformation.primary_phone' => $this->request->data['User']['primary_phone'],
        'PersonalInformation.dob' => $this->request->data['User']['dob'],
        'User.email' => $this->request->data['User']['email'],
    );



 $or = array_filter($or);

    $condition = array(
        'User.role' => array('U', 'P'),
        'User.user_status' => array('active', 'lead', 'inactive'),
        'OR' => $or
    );

1
これは何ですか?他にも非常に関連のある答えがたくさんあります。ここで何を追加しますか?
フェリックス・ガニオン-グルニエ

ここで質問の内容をURLで確認してください!! / *空の配列要素を削除* /
Ashish pathak

1

ここではarray_walkの方がはるかに適していると思います

$linksArray = array('name', '        ', '  342', '0', 0.0, null, '', false);

array_walk($linksArray, function(&$v, $k) use (&$linksArray){
    $v = trim($v);
    if ($v == '')
        unset($linksArray[$k]);
});
print_r($linksArray);

出力:

Array
(
    [0] => name
    [2] => 342
    [3] => 0
    [4] => 0
)
  • ユーザーが複数のスペースを追加した場合でも、空の値が削除されるようにしました
  • また、有効な値から空のスペースを削除しました

  • 最後に、(null)、(Boolean False)、( '')のみが空の文字列と見なされます

用としてFalse、それは私の知る限り、ユーザがブール値を送信することはできませんので、それを削除しても大丈夫です。


0

これらの種類のものでは、あなたが何を望んでいて何が望んでいないかを明示する方がはるかに良いです。

これはarray_filter()、コールバックなしの動作で次の男が驚きに巻き込まれないようにするのに役立ちます。たとえば、array_filter()削除するNULLかどうかを忘れたため、この質問に終わりました。以下の解決策を使うだけで時間を無駄にして答えが出ました。

また、ロジックは言語に依存しarray_filterないため、コールバックが渡されない場合のように、php関数の動作を理解する必要なく、コードを別の言語にコピーできます。

私の解決策では、何が起こっているのかが一目でわかります。条件を削除して何かを保持するか、新しい条件を追加して追加の値をフィルタリングします。

array_filter()カスタムコールバックを渡しているだけなので、実際の使用は無視してください。必要に応じて、それを独自の関数に抽出できます。foreachループの砂糖として使用しています。

<?php

$xs = [0, 1, 2, 3, "0", "", false, null];

$xs = array_filter($xs, function($x) {
    if ($x === null) { return false; }
    if ($x === false) { return false; }
    if ($x === "") { return false; }
    if ($x === "0") { return false; }
    return true;
});

$xs = array_values($xs); // reindex array   

echo "<pre>";
var_export($xs);

このアプローチのもう1つの利点は、フィルタリング述語を、配列ごとに1つの値をフィルタリングする抽象関数に分解し、構成可能なソリューションを構築できることです。

出力については、この例とインラインコメントを参照してください。

<?php

/**
 * @param string $valueToFilter
 *
 * @return \Closure A function that expects a 1d array and returns an array
 *                  filtered of values matching $valueToFilter.
 */
function filterValue($valueToFilter)
{
    return function($xs) use ($valueToFilter) {
        return array_filter($xs, function($x) use ($valueToFilter) {
            return $x !== $valueToFilter;
        });
    };
}

// partially applied functions that each expect a 1d array of values
$filterNull = filterValue(null);
$filterFalse = filterValue(false);
$filterZeroString = filterValue("0");
$filterEmptyString = filterValue("");

$xs = [0, 1, 2, 3, null, false, "0", ""];

$xs = $filterNull($xs);        //=> [0, 1, 2, 3, false, "0", ""]
$xs = $filterFalse($xs);       //=> [0, 1, 2, 3, "0", ""]
$xs = $filterZeroString($xs);  //=> [0, 1, 2, 3, ""]
$xs = $filterEmptyString($xs); //=> [0, 1, 2, 3]

echo "<pre>";
var_export($xs); //=> [0, 1, 2, 3]

これで、これらの部分的に適用された関数を適用する、filterer()using pipe()と呼ばれる関数を動的に作成できます。

<?php

/**
 * Supply between 1..n functions each with an arity of 1 (that is, accepts
 * one and only one argument). Versions prior to php 5.6 do not have the
 * variadic operator `...` and as such require the use of `func_get_args()` to
 * obtain the comma-delimited list of expressions provided via the argument
 * list on function call.
 *
 * Example - Call the function `pipe()` like:
 *
 *   pipe ($addOne, $multiplyByTwo);
 *
 * @return closure
 */
function pipe()
{
    $functions = func_get_args(); // an array of callable functions [$addOne, $multiplyByTwo]
    return function ($initialAccumulator) use ($functions) { // return a function with an arity of 1
        return array_reduce( // chain the supplied `$arg` value through each function in the list of functions
            $functions, // an array of functions to reduce over the supplied `$arg` value
            function ($accumulator, $currFn) { // the reducer (a reducing function)
                return $currFn($accumulator);
            },
            $initialAccumulator
        );
    };
}

/**
 * @param string $valueToFilter
 *
 * @return \Closure A function that expects a 1d array and returns an array
 *                  filtered of values matching $valueToFilter.
 */
function filterValue($valueToFilter)
{
    return function($xs) use ($valueToFilter) {
        return array_filter($xs, function($x) use ($valueToFilter) {
            return $x !== $valueToFilter;
        });
    };
}

$filterer = pipe(
    filterValue(null),
    filterValue(false),
    filterValue("0"),
    filterValue("")
);

$xs = [0, 1, 2, 3, null, false, "0", ""];
$xs = $filterer($xs);

echo "<pre>";
var_export($xs); //=> [0, 1, 2, 3]
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.