Dengan hal-hal semacam ini, jauh lebih baik untuk bersikap eksplisit tentang apa yang Anda inginkan dan tidak inginkan.
Ini akan membantu orang berikutnya untuk tidak terkejut dengan perilaku array_filter()
tanpa panggilan balik. Misalnya, saya berakhir dengan pertanyaan ini karena saya lupa apakah array_filter()
menghapus NULL
atau tidak. Saya membuang-buang waktu ketika saya bisa saja menggunakan solusi di bawah ini dan mendapatkan jawaban saya.
Juga, logikanya adalah bahasa angnostik dalam arti bahwa kode dapat disalin ke bahasa lain tanpa harus memahami perilaku fungsi php seperti array_filter
ketika tidak ada panggilan balik yang dilewatkan.
Dalam solusi saya, jelas sekali apa yang terjadi. Hapus persyaratan untuk menyimpan sesuatu atau menambahkan kondisi baru untuk memfilter nilai tambahan.
Abaikan penggunaan sebenarnya array_filter()
karena saya baru saja menyampaikannya sebagai panggilan balik kustom - Anda bisa melanjutkan dan mengekstraknya ke fungsinya sendiri jika Anda mau. Saya hanya menggunakannya sebagai gula untuk satu foreach
putaran.
<?php
$xs = [0, 1, 2, 3, "0", "", false, null];
$xs = array_filter($xs, function($x) {
if ($x === null) { return false; }
if ($x === false) { return false; }
if ($x === "") { return false; }
if ($x === "0") { return false; }
return true;
});
$xs = array_values($xs); // reindex array
echo "<pre>";
var_export($xs);
Manfaat lain dari pendekatan ini adalah Anda dapat memecah predikat pemfilteran menjadi fungsi abstrak yang memfilter nilai tunggal per larik dan membangun solusi komposabel.
Lihat contoh ini dan komentar sebaris untuk hasilnya.
<?php
/**
* @param string $valueToFilter
*
* @return \Closure A function that expects a 1d array and returns an array
* filtered of values matching $valueToFilter.
*/
function filterValue($valueToFilter)
{
return function($xs) use ($valueToFilter) {
return array_filter($xs, function($x) use ($valueToFilter) {
return $x !== $valueToFilter;
});
};
}
// partially applied functions that each expect a 1d array of values
$filterNull = filterValue(null);
$filterFalse = filterValue(false);
$filterZeroString = filterValue("0");
$filterEmptyString = filterValue("");
$xs = [0, 1, 2, 3, null, false, "0", ""];
$xs = $filterNull($xs); //=> [0, 1, 2, 3, false, "0", ""]
$xs = $filterFalse($xs); //=> [0, 1, 2, 3, "0", ""]
$xs = $filterZeroString($xs); //=> [0, 1, 2, 3, ""]
$xs = $filterEmptyString($xs); //=> [0, 1, 2, 3]
echo "<pre>";
var_export($xs); //=> [0, 1, 2, 3]
Sekarang Anda dapat secara dinamis membuat fungsi yang disebut filterer()
using pipe()
yang akan menerapkan fungsi-fungsi yang diterapkan sebagian ini untuk Anda.
<?php
/**
* Supply between 1..n functions each with an arity of 1 (that is, accepts
* one and only one argument). Versions prior to php 5.6 do not have the
* variadic operator `...` and as such require the use of `func_get_args()` to
* obtain the comma-delimited list of expressions provided via the argument
* list on function call.
*
* Example - Call the function `pipe()` like:
*
* pipe ($addOne, $multiplyByTwo);
*
* @return closure
*/
function pipe()
{
$functions = func_get_args(); // an array of callable functions [$addOne, $multiplyByTwo]
return function ($initialAccumulator) use ($functions) { // return a function with an arity of 1
return array_reduce( // chain the supplied `$arg` value through each function in the list of functions
$functions, // an array of functions to reduce over the supplied `$arg` value
function ($accumulator, $currFn) { // the reducer (a reducing function)
return $currFn($accumulator);
},
$initialAccumulator
);
};
}
/**
* @param string $valueToFilter
*
* @return \Closure A function that expects a 1d array and returns an array
* filtered of values matching $valueToFilter.
*/
function filterValue($valueToFilter)
{
return function($xs) use ($valueToFilter) {
return array_filter($xs, function($x) use ($valueToFilter) {
return $x !== $valueToFilter;
});
};
}
$filterer = pipe(
filterValue(null),
filterValue(false),
filterValue("0"),
filterValue("")
);
$xs = [0, 1, 2, 3, null, false, "0", ""];
$xs = $filterer($xs);
echo "<pre>";
var_export($xs); //=> [0, 1, 2, 3]