Cara menggunakan php array filter multidimensional

Fungsi panggilan balik di array_filter() hanya melewati nilai array, bukan kunci.

Jika saya punya:

$my_array = array("foo" => 1, "hello" => "world"); $allowed = array("foo", "bar");

Apa cara terbaik untuk menghapus semua kunci di $my_array yang tidak ada dalam array $allowed?

Output yang diinginkan:

$my_array = array("foo" => 1);

PHP 5.6 memperkenalkan parameter ketiga ke array_filter(), flag , yang dapat Anda atur ke ARRAY_FILTER_USE_KEY untuk difilter dengan kunci alih-alih nilai:

$my_array = ['foo' => 1, 'hello' => 'world']; $allowed = ['foo', 'bar']; $filtered = array_filter( $my_array, function ($key) use ($allowed) { return in_array($key, $allowed); }, ARRAY_FILTER_USE_KEY );

Jelas ini tidak seanggun array_intersect_key($my_array, array_flip($allowed)) , tetapi memang menawarkan fleksibilitas tambahan untuk melakukan uji arbitrer terhadap kunci, mis. $allowed dapat berisi pola regex alih-alih string biasa.

Anda juga dapat menggunakan ARRAY_FILTER_USE_BOTH untuk memiliki nilai dan kunci yang diteruskan ke fungsi filter Anda. Berikut adalah contoh yang dibuat berdasarkan yang pertama, tetapi perhatikan bahwa saya tidak akan merekomendasikan penyandian aturan penyaringan menggunakan $allowed dengan cara ini:

$my_array = ['foo' => 1, 'bar' => 'baz', 'hello' => 'wld']; $allowed = ['foo' => true, 'bar' => true, 'hello' => 'world']; $filtered = array_filter( $my_array, function ($val, $key) use ($allowed) { // N.b. $val, $key not $key, $val return isset($allowed[$key]) && ( $allowed[$key] === true || $allowed[$key] === $val ); }, ARRAY_FILTER_USE_BOTH ); // ['foo' => 1, 'bar' => 'baz']

Saya perlu melakukan hal yang sama, tetapi dengan array_filter yang lebih kompleks pada tombol. 

Begini cara saya melakukannya, menggunakan metode yang serupa.

// Filter out array elements with keys shorter than 4 characters $a = array( 0 => "val 0", "one" => "val one", "two" => "val two", "three"=> "val three", "four" => "val four", "five" => "val five", "6" => "val 6" ); $f = array_filter(array_keys($a), function ($k){ return strlen($k)>=4; }); $b = array_intersect_key($a, array_flip($f)); print_r($b);

Ini menghasilkan hasilnya:

Array ( [three] => val three [four] => val four [five] => val five )

Berikut ini adalah solusi yang lebih fleksibel menggunakan penutupan:

$my_array = array("foo" => 1, "hello" => "world"); $allowed = array("foo", "bar"); $result = array_flip(array_filter(array_flip($my_array), function ($key) use ($allowed) { return in_array($key, $allowed); })); var_dump($result);

Output:

array(1) { 'foo' => int(1) }

Jadi dalam fungsinya, Anda bisa melakukan tes khusus lainnya.

Cara mendapatkan kunci array saat ini saat menggunakan array_filter

Terlepas dari bagaimana saya suka solusi Vincent untuk masalah Maček, itu sebenarnya tidak menggunakan array_filter. Jika Anda datang ke sini dari mesin pencari, Anda mungkin mencari tempat seperti ini ( PHP> = 5.3 ):

$array = ['Apple' => 'red', 'pear' => 'green']; reset($array); // Unimportant here, but make sure your array is reset $apples = array_filter($array, function($color) use ($&array) { $key = key($array); next($array); // advance array pointer return key($array) === 'Apple'; }

Melewati array yang Anda filter sebagai referensi ke callback. Karena array_filter tidak secara konvensional beralih ke array dengan meningkatkan itu pointer internal publik Anda harus memajukannya sendiri.

Yang penting di sini adalah Anda perlu memastikan array Anda disetel ulang, jika tidak Anda bisa mulai tepat di tengahnya.

Di PHP> = 5,4 Anda bisa membuat panggilan balik lebih pendek:

$apples = array_filter($array, function($color) use ($&array) { return each($array)['key'] === 'Apple'; }

Jika Anda mencari metode untuk memfilter array dengan string yang terjadi pada kunci, Anda dapat menggunakan:

$mArray=array('foo'=>'bar','foo2'=>'bar2','fooToo'=>'bar3','baz'=>'nope'); $mSearch='foo'; $allowed=array_filter( array_keys($mArray), function($key) use ($mSearch){ return stristr($key,$mSearch); }); $mResult=array_intersect_key($mArray,array_flip($allowed));

Hasil dari print_r($mResult) adalah 

Array ( [foo] => bar [foo2] => bar2 [fooToo] => bar3 )

Adaptasi jawaban ini yang mendukung ekspresi reguler

function array_preg_filter_keys($arr, $regexp) { $keys = array_keys($arr); $match = array_filter($keys, function($k) use($regexp) { return preg_match($regexp, $k) === 1; }); return array_intersect_key($arr, array_flip($match)); } $mArray = array('foo'=>'yes', 'foo2'=>'yes', 'FooToo'=>'yes', 'baz'=>'nope'); print_r(array_preg_filter_keys($mArray, "/^foo/i"));

Keluaran

Array ( [foo] => yes [foo2] => yes [FooToo] => yes )

Berikut alternatif yang kurang fleksibel menggunakan tidak disetel () :

$array = array( 1 => 'one', 2 => 'two', 3 => 'three' ); $disallowed = array(1,3); foreach($disallowed as $key){ unset($array[$key]); }

Hasil dari print_r($array) adalah:

Array ( [2] => two )

Ini tidak berlaku jika Anda ingin menyimpan nilai difilter untuk digunakan nanti tetapi lebih rapi, jika Anda yakin tidak.

Mulai dari PHP 5.6, Anda dapat menggunakan flag ARRAY_FILTER_USE_KEY di array_filter :

$result = array_filter($my_array, function ($k) use ($allowed) { return in_array($k, $allowed); }, ARRAY_FILTER_USE_KEY);


Jika tidak, Anda dapat menggunakan fungsi ini ( dari TestDummy ):

function filter_array_keys(array $array, $callback) { $matchedKeys = array_filter(array_keys($array), $callback); return array_intersect_key($array, array_flip($matchedKeys)); } $result = filter_array_keys($my_array, function ($k) use ($allowed) { return in_array($k, $allowed); });


Dan di sini adalah versi augmented milik saya, yang menerima panggilan balik atau langsung kunci:

function filter_array_keys(array $array, $keys) { if (is_callable($keys)) { $keys = array_filter(array_keys($array), $keys); } return array_intersect_key($array, array_flip($keys)); } // using a callback, like array_filter: $result = filter_array_keys($my_array, function ($k) use ($allowed) { return in_array($k, $allowed); }); // or, if you already have the keys: $result = filter_array_keys($my_array, $allowed));


Last but not least, Anda juga dapat menggunakan foreach sederhana:

$result = []; foreach ($my_array as $key => $value) { if (in_array($key, $allowed)) { $result[$key] = $value; } }

Mungkin berlebihan jika Anda membutuhkannya sekali saja, tetapi Anda dapat menggunakan pustaka YaLinqo * untuk memfilter koleksi (dan melakukan transformasi lainnya). Pustaka ini memungkinkan melakukan kueri seperti SQL pada objek dengan sintaks yang lancar. Fungsinya where menerima calback dengan dua argumen: nilai dan kunci. Sebagai contoh:

$filtered = from($array) ->where(function ($v, $k) use ($allowed) { return in_array($k, $allowed); }) ->toArray();

(Fungsi where mengembalikan iterator, jadi jika Anda hanya perlu mengulangi dengan foreach atas urutan yang dihasilkan satu kali, ->toArray() dapat dihapus.)

* Dikembangkan oleh saya

fungsi filter array dari php:

array_filter ( $array, $callback_function, $flag )

$ array - Ini adalah array input

$ callback_function - Fungsi callback yang digunakan , Jika fungsi callback mengembalikan true, nilai saat ini dari array dikembalikan ke array hasil.

$ flag - Ini parameter opsional, itu akan menentukan argumen apa yang dikirim ke fungsi callback. Jika parameter ini kosong maka fungsi callback akan mengambil nilai array sebagai argumen. Jika Anda ingin mengirim kunci array sebagai argumen, gunakan $ flag sebagai ARRAY_FILTER_USE_KEY. Jika Anda ingin mengirim kunci dan nilai, Anda harus menggunakan $ flag sebagai ARRAY_FILTER_USE_BOTH.

Sebagai Contoh: Pertimbangkan array sederhana

$array = array("a"=>1, "b"=>2, "c"=>3, "d"=>4, "e"=>5);

Jika Anda ingin memfilter array berdasarkan kunci array, Kita perlu menggunakan ARRAY_FILTER_USE_KEY sebagai parameter ketiga dari array function array_filter.

$get_key_res = array_filter($array,"get_key",ARRAY_FILTER_USE_KEY );

Jika Anda ingin memfilter array berdasarkan kunci array dan nilai array, Kita perlu menggunakan ARRAY_FILTER_USE_BOTH sebagai parameter ketiga dari array function array_filter.

$get_both = array_filter($array,"get_both",ARRAY_FILTER_USE_BOTH );

Contoh fungsi Panggilan Balik:

function get_key($key) { if($key == 'a') { return true; } else { return false; } } function get_both($val,$key) { if($key == 'a' && $val == 1) { return true; } else { return false; } }

Ini akan menampilkan 

Output of $get_key is :Array ( [a] => 1 ) Output of $get_both is :Array ( [a] => 1 )

Dengan fungsi ini Anda dapat memfilter array multidimensi

function filter_array_keys($array,$filter_keys=array()){ $l=array(&$array); $c=1; //This first loop will loop until the count var is stable// for($r=0;$r<$c;$r++){ //This loop will loop thru the child element list// $keys = array_keys($l[$r]); for($z=0;$z<count($l[$r]);$z++){ $object = &$l[$r][$keys[$z]]; if(is_array($object)){ $i=0; $keys_on_array=array_keys($object); $object=array_filter($object,function($el) use(&$i,$keys_on_array,$filter_keys){ $key = $keys_on_array[$i]; $i++; if(in_array($key,$filter_keys) || is_int($key))return false; return true; }); } if(is_array($l[$r][$keys[$z]])){ $l[] = &$l[$r][$keys[$z]]; $c++; }//IF }//FOR }//FOR return $l[0]; }

// Menyaring elemen array dengan tombol yang lebih pendek dari 4 karakter // Dengan menggunakan fungsi Anonim dengan ... 

function comparison($min) { return function($item) use ($min) { return strlen($item) >= $min; }; } $input = array( 0 => "val 0", "one" => "val one", "two" => "val two", "three"=> "val three", "four" => "val four", "five" => "val five", "6" => "val 6" );

$ output = array_filter (array_keys ($ input), perbandingan (4)); 

print_r ($ output);
 

Postingan terbaru

LIHAT SEMUA