array_filter()の後で、キーをリセットして0から始まる番号順に移動するにはどうすればよいですか?


108

array_filterを使用して、値が ''のみのエントリを配列から削除しました。ここで、0から始まるプレースホルダーに応じて特定の変換を適用しますが、残念ながら元のインデックスは保持されます。しばらく探していて何も見えなかったのですが、おそらく明白なものを逃しただけかもしれませんが、私の質問は...

古い配列を保持するのではなく、配列のインデックスを0から開始して新しい配列を順番に並べ替えるにはどうすればよいですか?



配列に空/ゼロっぽい/偽の値がないことが確実である場合を除いて、使用しないように強くお勧めしますarray_filter()。意図した以上にパージする可能性があります。ここでは、デモといくつかの説明は次のとおりです。stackoverflow.com/a/43657056/2943403
mickmackusaは

回答:



37

配列フィルターを使用している場合は、次のようにします

$NewArray = array_values(array_filter($OldArray));

3
json_encodeの結果がarray_filtered配列のjson_encodeの結果と異なる理由を理解しようとするのに時間を費やしてしまった...ありがとうございます...
Jerther

13

何人のプログラマーが無邪気にarray_values(array_filter())メソッドをコードにコピー/ペーストしたのか心配しています -array_filterの貪欲さのために、無意識のうちに何人のプログラマーが問題に遭遇したのでしょうか。さらに悪いことに、関数が配列からあまりにも多くの値を削除することを発見したことがない人の数...

NULL配列から要素を取り除き、キーのインデックスを再作成するという2つの部分からなるプロセスのより良い代替案を紹介します。

ただし、最初に、私は貪欲な性質を強調し、array_filter()これがどのようにして静かにプロジェクトをモンキーレンチすることができるかを強調することが非常に重要です。ここに問題を露呈する混合値の配列があります:

$array=['foo',NULL,'bar',0,false,null,'0',''];

ヌル値は、大文字/小文字に関係なく削除されます。

しかし、array_values()array_filter()を使用するときに配列に残っているものを見てください。

array_values(array_filter($array));

出力配列($ array):

array (
  0 => 'foo',
  1 => 'bar'
)
// All empty, zero-ish, falsey values were removed too!!!

次に、array_walk()およびis_null()を使用して新しいフィルター処理された配列を生成する私のメソッドで得られる結果を確認します。

array_walk($array,function($v)use(&$filtered){if(!is_null($v)){$filtered[]=$v;}});

これは、読みやすく/説明しやすいように、複数行にわたって書くことができます。

array_walk(                      // iterate each element of an input array
    $array,                      // this is the input array
    function($v)use(&$filtered){ // $v is each value, $filter (output) is declared/modifiable
        if(!is_null($v)){        // this literally checks for null values
            $filtered[]=$v;      // value is pushed into output with new indexes
        }
    }
);

出力配列($ filter):

array (
  0 => 'foo',
  1 => 'bar',
  2 => 0,
  3 => false,
  4 => '0',
  5 => '',
)

私の方法では、再インデックスされたキー、すべての非null値を取得し、null値は取得しません。配列のすべてのヌルフィルタリングのニーズに対応する、クリーンでポータブルで信頼性の高いワンライナー。こちらがデモです。



同様に、空の要素、false要素、null要素(ゼロを保持)を削除する場合は、次の4つのメソッドが機能します。

var_export(array_values(array_diff($array,[''])));

または

var_export(array_values(array_diff($array,[null])));

または

var_export(array_values(array_diff($array,[false])));

または

var_export(array_values(array_filter($array,'strlen')));

出力:

array (
  0 => 'foo',
  1 => 'bar',
  2 => 0,
  3 => '0',
)

最後に、言語構造の構文を好む人にとっては、修飾値を新しい配列にプッシュして、新しいインデックスを発行することもできます。

$array=['foo', NULL, 'bar', 0, false, null, '0', ''];

$result = [];
foreach ($array as $value) {
    if (strlen($value)) {
        $result[] = $value;
    }
}

var_export($result);

2
あなたが書いた場合、物事は期待どおりに動作しませんarray_values(array_filter($arr, function($el) {return $el !== '';}))か?これは、OPが要求することを行う自然な方法のようです。
ケーシー

1
はい。私のポイントは、開発者はarray_filter()データの親密な知識が副作用なしの貪欲なフィルタリングを許可しない限り、デフォルトの動作を使用するという衝動を避けるべきであるということです。(さらに注意:empty()同じ方法で動作し、貪欲に空の配列も含まれます。)
mickmackusa

2
この回答は、元の質問とはまったく関係のない、まったく別の質問に答えるものです。
AnrDaemon

1
array_filter()まさにあなたのように振る舞うが、それは手動で言っていることに基づいて、期待したい:php.net/manual/en/function.array-filter.php コールバックを指定しない場合、配列のすべてのエントリがFALSEに等しい」(ブール値への変換を参照してください)は削除されます。」そして、0、null、false、 ''、および '0'がブール値に強制変換されたときにすべてfalseと評価されることは、PHPプログラマーの間で共通の知識であるはずです。
madsen

1
ことは、ほとんどの人は何を期待するのか分からないということです。あなたはそうします、私はしますが、多くはしません。私は知らない人を助けるためにこの回答を投稿しました。
mickmackusa

12

使用array_values()

<?php

$array = array('foo', 'bar', 'baz');
$array = array_filter($array, function ($var) {
    return $var !== 'bar';
});

print_r($array); // indexes 0 and 2
print_r(array_values($array)); // indexes 0 and 1
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.