foreachループで配列要素を削除するにはどうすればよいですか?


127

foreach値が存在するかどうかを確認するために配列をループしたいのですが。値が存在する場合は、それを含む要素を削除します。

私は次のコードを持っています:

foreach($display_related_tags as $tag_name) {
    if($tag_name == $found_tag['name']) {
        // Delete element
    }
}

値が見つかったら、要素を削除する方法がわかりません。どうすれば削除できますか?

私はforeachこの問題に使用しなければなりません。に代わるものはおそらくありforeach、それらを共有することを歓迎します。

回答:


219

キーも取得した場合は、次のようにそのアイテムを削除できます。

foreach ($display_related_tags as $key => $tag_name) {
    if($tag_name == $found_tag['name']) {
        unset($display_related_tags[$key]);
    }
}


5
項目が設定されていないインデックス付き配列は、の後の配列ではなくオブジェクトとして表される場合があることに注意してくださいjson_encode()。これ$display_related_tags = array_values ($display_related_tags);foreachループの後で解決できます。
マートンタマシュ

ここでの秘訣は、値をforeachループに追加することです;-)
ワシントン氏

5
@Neilsの回答をご覧ください。特にstdClassesの配列を使用している場合は、予期しないバグが発生します。予期しない動作が好きですか?私じゃない。
happy_marmoset 2016

@happy_marmoset Neilsの答えは役に立ちません。$projects = array_filter($projects, function ($project) { return count($project->roles) > 0; });結果をオブジェクトに変換するスニペット。
パリトッシュ2016年

36

より良い解決策は、array_filter関数を使用することです:

$display_related_tags =
    array_filter($display_related_tags, function($e) use($found_tag){
        return $e != $found_tag['name'];
    });

phpのドキュメントを読むと:

foreachはPHP 5の内部配列ポインターに依存しているため、ループ内で変更すると、予期しない動作が発生する可能性があります。

PHP 7では、foreachは内部配列ポインターを使用しません。


ここで$ eとしてキーを渡すには、3番目のパラメーターがARRAY_FILTER_USE_KEYである必要があることに注意してください。
namezero 2018

@namezero OKどうしてここで問題なのですか?
AbraCadaver

@AbraCadaverドキュメンテーション(php.net/manual/en/function.array-filter.php)から: ARRAY_FILTER_USE_KEY - pass key as the only argument to callback instead of the value ARRAY_FILTER_USE_BOTH - pass both value and key as arguments to callback instead of the value Default is 0 which will pass value as the only argument to callback instead. つまり、この場合、もう一度答えを読むことはもちろん主張するほど重要ではありません。
namezero

重要配列を順序付けられた配列として保持することに関心がある場合は、display_related_tags = array_values(display_related_tags);その後で呼び出す必要があります。
guyaloni

9
foreach($display_related_tags as $key => $tag_name)
{
    if($tag_name == $found_tag['name'])
        unset($display_related_tags[$key];
}

3
'unlink'はファイルのリンクを解除します。変数や、より具体的には配列とは関係ありません。おそらくあなたは「未設定」を意味しますか?
午前

6

配列に対してforeach()ループを実行する代わりに、array_search()を使用して適切なキーを見つける方が高速です。小さい配列では、読みやすくするためにforeachを使用しますが、大きい配列または頻繁に実行されるコードの場合、これは少し最適なはずです。

$result=array_search($unwantedValue,$array,true);
if($result !== false) {
  unset($array[$result]);   
}

array_search()は$ unwantedValueのインデックスとして0を返すことができるため、厳密な比較演算子!==が必要です。

また、上記の例では、最初の値$ unwantedValueのみが削除されます。$ unwantedValueが$ arrayで複数回発生する可能性がある場合は、array_keys()を使用してすべてを検索する必要があります。

$result=array_keys($array,$unwantedValue,true)
foreach($result as $key) {
  unset($array[$key]);
}

詳細については、http://php.net/manual/en/function.array-search.phpを確認してください。


0

この場合、foreach配列から複数の値を削除する必要があるシナリオがある場合は、それぞれに値を参照渡しする必要があります。このシナリオを説明しようとします。

foreach ($manSkuQty as $man_sku => &$man_qty) {

               foreach ($manufacturerSkus as $key1 => $val1) {

  // some processing here and unset first loops entries                     
 //  here dont include again for next iterations
                           if(some condition)
                            unset($manSkuQty[$key1]);

                        }
               }
}

2番目のループでは、最初のループの設定を解除する必要があります。パフォーマンスの目的で、反復でエントリが再び発生しないか、メモリから設定が解除されます。


0

解き方を明らかにする答えがすでにあります。すべてのクラスでコードを繰り返すのではなく、以下のように機能させ、必要に応じてコードで使用します。ビジネスロジックでは、一部のプロパティを公開したくない場合があります。削除するには、以下のライナーコールを参照してください

public static function removeKeysFromAssociativeArray($associativeArray, $keysToUnset)
{
    if (empty($associativeArray) || empty($keysToUnset))
        return array();

    foreach ($associativeArray as $key => $arr) {
        if (!is_array($arr)) {
            continue;
        }

        foreach ($keysToUnset as $keyToUnset) {
            if (array_key_exists($keyToUnset, $arr)) {
                unset($arr[$keyToUnset]);
            }
        }
        $associativeArray[$key] = $arr;
    }
    return $associativeArray;
}

次のように呼び出します:

removeKeysFromAssociativeArray($arrValues, $keysToRemove);

-1

すでに述べたように、キーを使用してforeachを実行し、キーを使用して設定を解除することをお勧めします。ただし、PHPのルールについてはよくわかりませんが、反復中に配列を変更することは一般的に悪い考えです。オフハンド。


2
php foreachは、アレイ全体で実行されます。イテレーションの次の値の設定解除をテストします。オフセットで反復しますが、値はnullになります。
Kevin Peno

反復中に配列を変更しない場合、配列を変更するにはどうすればよいですか?一般的に、反復ではなく、意地悪foreachまたはfor構造ですか?
ガーマン

これは、答えそのものではなく、別の答えに関するコメントです。
Sinister Beard
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.