Apakah mungkin, dalam PHP, untuk meratakan array dimensi (bi / multi) tanpa menggunakan rekursi atau referensi?
Saya hanya tertarik pada nilai-nilai sehingga kunci dapat diabaikan, saya berpikir dalam garis array_map()
dan array_values()
.
php
arrays
multidimensional-array
flatten
Alix Axel
sumber
sumber
Jawaban:
Anda dapat menggunakan Perpustakaan PHP Standar (SPL) untuk "menyembunyikan" rekursi.
cetakan
sumber
iterator_to_array($it, false)
menghindari perlunya foreach.function flatten($arr){ $it = new RecursiveIteratorIterator(new RecursiveArrayIterator($arr)); return iterator_to_array($it, true); }
Semoga ini bisa membantu orang lain.Pada PHP 5.3 solusi terpendek tampaknya adalah
array_walk_recursive()
dengan sintaks penutupan baru:sumber
use
sintaks untuk membuatnya bekerjaarray_walk_recursive
karena tidak akan menerima$userdata
parameter opsional dengan referensiSolusi untuk array 2 dimensi
Silakan coba ini:
EDIT: 21-Aug-13
Inilah solusi yang berfungsi untuk array multi dimensi:
Ref: http://php.net/manual/en/function.call-user-func-array.php
sumber
call_user_func_array('array_merge', [])
(perhatikan array kosong) mengembalikan nol dan memicu kesalahan peringatan php. Ini adalah solusi yang apik jika Anda tahu fakta bahwa array Anda tidak akan kosong, tapi itu bukan asumsi umum yang bisa dibuat banyak orang.$result = $array ?call_user_func_array('array_merge', $array) : [];
Dalam PHP 5.6 dan di atasnya Anda dapat meratakan array dua dimensi dengan
array_merge
setelah membongkar array luar dengan...
operator. Kode ini sederhana dan jelas.Ini bekerja dengan kumpulan array asosiatif juga.
Tapi itu tidak berfungsi ketika array luar memiliki kunci non numerik. Dalam hal ini, Anda harus menelepon
array_values
dulu.Pembaruan: Berdasarkan komentar oleh @MohamedGharib
Ini akan menimbulkan kesalahan jika array luar kosong, karena
array_merge
akan dipanggil dengan argumen nol. Ini bisa dihindari dengan menambahkan array kosong sebagai argumen pertama.sumber
array_merge([], ...$a);
Untuk meratakan tanpa rekursi (seperti yang Anda minta), Anda dapat menggunakan tumpukan . Secara alami Anda dapat menempatkan ini ke dalam fungsi itu sendiri seperti
array_flatten
. Berikut ini adalah versi yang berfungsi tanpa kunci :.Elemen diproses dalam urutannya. Karena subelemen akan dipindahkan di atas tumpukan, mereka akan diproses berikutnya.
Dimungkinkan juga untuk memasukkan kunci, tetapi Anda memerlukan strategi berbeda untuk menangani tumpukan. Itu diperlukan karena Anda perlu menangani kemungkinan kunci duplikat di sub-array. Jawaban serupa dalam pertanyaan terkait: PHP Berjalan melalui array multidimensi sambil mempertahankan kunci
Saya tidak terlalu yakin, tetapi saya telah menguji ini di masa lalu:
RecurisiveIterator
Menggunakan rekursi, jadi itu tergantung pada apa yang Anda butuhkan. Seharusnya dimungkinkan untuk membuat iterator rekursif berdasarkan tumpukan juga:Demo
Saya tidak sampai sejauh ini, untuk mengimplementasikan stack berdasarkan
RecursiveIterator
yang menurut saya adalah ide yang bagus.sumber
if(!empty($value)){$flat[] = $value}
di dalam pernyataan lain untuk mencegah kosong yang ditambahkan ke array hasil. Fungsi luar biasa!Langsung dan Satu-liner jawaban.
Pemakaian:
Output (dalam PsySH):
Sekarang terserah Anda sekarang bagaimana Anda akan menangani kunci. Bersulang
EDIT (2017-03-01)
Mengutip kekhawatiran / masalah Nigel Alderton :
Mengutip jawaban Svish :
sumber
$array = ['a',['b','c']]
menjadiArray ([0] => b, [1] => c )
. The'a'
hilang karena'b'
juga memiliki kunci0
.false
sebagai parameter kedua ($use_keys
) keiterator_to_array
panggilan.Gunakan rekursi. Mudah-mudahan setelah melihat betapa tidak rumitnya hal itu, ketakutan Anda akan rekursi akan hilang begitu Anda melihat betapa tidak rumitnya itu.
Keluaran:
sumber
Hanya berpikir saya akan menunjukkan bahwa ini adalah lipatan, jadi array_reduce dapat digunakan:
EDIT: Perhatikan bahwa ini dapat disusun untuk meratakan sejumlah level. Kita dapat melakukan ini dalam beberapa cara:
Tentu saja, kita juga bisa menggunakan loop tetapi pertanyaannya meminta fungsi kombinator di sepanjang baris array_map atau array_values.
sumber
fold
membuatnya menjadi 4 level, ataufold . fold
untuk mendapatkan 3 level, ataufold . fold . fold
untuk mendapatkan 2 level, dll. Ini juga mencegah bug disembunyikan; misalnya. jika saya ingin meratakan array 5D tapi saya diberi array 4D, kesalahan akan langsung terpicu.$concat
, saya pikir Anda harus menyebutnya saja$flatten
.array_merge
adalah setara dengan php dari concat. Saya mencoba untukarray_concat
ditambahkan sebagai alias untukarray_merge
.Ratakan hanya array dua dimensi:
sumber
Solusi ini non-rekursif. Perhatikan bahwa urutan elemen akan agak tercampur.
sumber
shifting
nilai dari array dan menambahkannya lagi sampai akhir tidak masuk akal. Saya kira Anda inginarray_merge()
bukan?Saya percaya ini adalah solusi terbersih tanpa menggunakan mutasi atau kelas yang tidak dikenal.
sumber
Coba fungsi sederhana berikut ini:
Jadi dari ini:
Anda mendapatkan:
sumber
Triknya adalah melewati array sumber dan tujuan dengan referensi.
sumber
Cuplikan inti
sumber
Anda dapat melakukannya dengan barang ouzo :
Lihat: Di Sini
sumber
Jika Anda benar-benar tidak menyukai rekursi ... coba ganti saja :)
Catatan: Dalam versi sederhana ini, ini tidak mendukung kunci array.
sumber
continue
, itu agak lebih cepat.Bagaimana dengan menggunakan generator rekursif? https://ideone.com/d0TXCg
sumber
Untuk php 5.2
sumber
Versi ini dapat melakukan level yang dalam, dangkal, atau jumlah tertentu:
sumber
Karena kode di sini terlihat menyeramkan. Berikut adalah fungsi yang juga akan mengubah array multidimensi menjadi sintaks yang kompatibel dengan bentuk html, tetapi lebih mudah dibaca.
sumber
Ini bisa dicapai dengan menggunakan
array_walk_recursive
Contoh kerja: - https://3v4l.org/FpIrG
sumber
Ini solusi saya, menggunakan referensi:
sumber
sumber
Inilah pendekatan sederhana:
sumber
Siapa pun yang mencari solusi yang sangat bersih untuk ini; inilah pilihannya:
Cetakan
sumber
Hanya memposting solusi lain)
sumber
Jika Anda ingin menyimpan juga kunci Anda, itu adalah solusi.
Sayangnya ini hanya menghasilkan array bersarang akhir, tanpa tombol tengah. Jadi untuk contoh berikut:
Output adalah:
sumber
Saya perlu mewakili array multidimensi PHP dalam format input HTML.
sumber
$var['a']['b']['c'][0] = 'a'; ...
.Jika Anda memiliki array objek dan ingin meratakannya dengan sebuah simpul, cukup gunakan fungsi ini:
sumber