Bagaimana Anda menghapus elemen array di loop foreach?


127

Saya ingin mengulang melalui array dengan foreachuntuk memeriksa apakah ada nilai. Jika nilainya ada, saya ingin menghapus elemen yang berisi itu.

Saya memiliki kode berikut:

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

Saya tidak tahu cara menghapus elemen setelah nilainya ditemukan. Bagaimana cara menghapusnya?

Saya harus menggunakan foreachuntuk masalah ini. Mungkin ada alternatif lain foreach, dan Anda dipersilakan untuk membagikannya.

Jawaban:


220

Jika Anda juga mendapatkan kuncinya, Anda dapat menghapus item itu seperti ini:

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

3
Beberapa info tambahan tentang pengoptimalan dengan menggunakan $key => &$tag_name stackoverflow.com/a/2008893/922522
Justin

5
Perhatikan bahwa array yang diindeks dengan item yang tidak disetel dapat direpresentasikan sebagai objek, bukan array setelah a json_encode(). Anda dapat menyelesaikan ini dengan $display_related_tags = array_values ($display_related_tags);setelah foreachloop.
Márton Tamás

Perhatikan bahwa trik di sini adalah menambahkan nilai ke loop foreach ;-)
Mr Washington

5
Silakan lihat jawaban @Neils. Anda akan menemui bug yang tidak terduga, terutama jika Anda bekerja dengan Array stdClasses. Apakah Anda menyukai perilaku yang tidak terduga? Saya tidak.
happy_marmoset

@happy_marmoset Jawaban Neils tidak membantu. Potongan $projects = array_filter($projects, function ($project) { return count($project->roles) > 0; });itu mengubah hasil menjadi objek.
Paritosh

36

Solusi yang lebih baik adalah dengan menggunakan array_filterfungsi:

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

Seperti yang tertulis dalam dokumentasi php :

Karena foreach bergantung pada pointer array internal di PHP 5, mengubahnya di dalam loop dapat menyebabkan perilaku yang tidak terduga.

Di PHP 7, foreach tidak menggunakan pointer array internal.


Perhatikan bahwa parameter ke-3 harus ARRAY_FILTER_USE_KEY untuk meneruskan kunci sebagai $ e di sini.
namezero

@namezero OK mengapa itu penting di sini?
AbraCadaver

@AbraCadaver Dari dokumentasi ( php.net/manual/en/function.array-filter.php ): Meskipun demikianARRAY_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. , membaca jawaban lagi dalam kasus ini tentu saja tidak masalah seperti yang Anda klaim.
namezero

Penting Jika Anda tertarik untuk mempertahankan array sebagai array yang dipesan, Anda perlu memanggilnya display_related_tags = array_values(display_related_tags);setelahnya.
guyaloni

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

3
'unlink' unlinks file, ini tidak ada hubungannya dengan variabel atau, lebih khusus lagi, array. Mungkin maksud Anda 'tidak disetel'?
amn

6

Alih-alih melakukan perulangan foreach () pada array, akan lebih cepat menggunakan array_search () untuk menemukan kunci yang tepat. Pada array kecil, saya akan menggunakan foreach untuk readibility yang lebih baik, tetapi untuk array yang lebih besar, atau kode yang sering dieksekusi, ini harus sedikit lebih optimal:

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

Operator perbandingan ketat! == diperlukan, karena array_search () bisa mengembalikan 0 sebagai indeks dari $ unwantedValue.

Juga, contoh di atas hanya akan menghapus nilai pertama $ unwantedValue, jika $ unwantedValue bisa muncul lebih dari sekali dalam $ array, Anda harus menggunakan array_keys (), untuk menemukan semuanya:

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

Periksa http://php.net/manual/en/function.array-search.php untuk informasi lebih lanjut.


0

jika Anda memiliki skenario di mana Anda harus menghapus lebih dari satu nilai dari larik foreach dalam hal ini Anda harus meneruskan nilai dengan referensi di masing-masing: Saya mencoba menjelaskan skenario ini:

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]);

                        }
               }
}

dalam loop kedua Anda ingin menghapus entri loop pertama jangan datang lagi dalam iterasi untuk tujuan kinerja atau kemudian hapus dari memori juga karena dalam memori mereka hadir dan akan datang dalam iterasi.


0

Sudah ada jawaban yang memberi penjelasan tentang cara tidak disetel. Daripada mengulang kode di semua kelas Anda, buat fungsi seperti di bawah ini dan gunakan dalam kode kapan pun diperlukan. Dalam logika bisnis, terkadang Anda tidak ingin mengekspos beberapa properti. Silakan lihat di bawah satu panggilan liner untuk menghapus

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;
}

Panggilan seperti:

removeKeysFromAssociativeArray($arrValues, $keysToRemove);

-1

Seperti yang telah disebutkan, Anda ingin melakukan foreach dengan kuncinya, dan membatalkan pengaturan menggunakan kuncinya - tetapi perhatikan bahwa mutasi array selama iterasi secara umum adalah ide yang buruk, meskipun saya tidak yakin dengan aturan PHP tentang ini begitu saja.


2
Sebuah php foreach akan dieksekusi pada seluruh array. Uji unsetting nilai yang berikutnya dalam iterasi. Ini akan mengulang pada offset, tetapi nilainya akan menjadi nol.
Kevin Peno

Jika Anda tidak mengubah array selama iterasi, lalu bagaimana cara mengubah array sama sekali? Mungkin berarti foreachatau forkonstruksi daripada iterasi secara umum?
Gherman

Ini lebih merupakan komentar atas jawaban lain daripada jawaban itu sendiri.
Sinister Beard
Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.