我正在编写一个名为all
的函数来检查数组$arr
内的所有元素,返回一个boolean
值(基于$f
返回值)。这可以很好地传递自定义函数(请参阅$gte0
的代码已传递给all
)。
但有时人们只想检查一个数组是否包含所有true
值:all(true, $arr)
将无法正常工作,因为true
传递为boolean
(和true
不是函数名称)。 PHP是否具有本机true()
之类的功能?
function all($f, array $arr)
{
return empty($arr) ? false : array_reduce($arr, function($v1, $v2) use ($f) {
return $f($v1) && $f($v2);
}, true);
}
$test = array(1, 6, 2);
$gte0 = function($v) { return $v >= 0; }
var_dump(all($gte0, $test)); // True
$test = array(true, true, false);
$id = function($v) { return $v; } // <-- this is what i would avoid
var_dump(all($id, $test)); // False
all(true, $test); // NOT WORKING because true is passed as boolean
all('true', $test); // NOT WORKING because true is not a function
编辑:另一种方法是检查$f
函数中的all
:
$f = is_bool($f) ? ($f ? function($v) { return $v; }
: function($v) { return !$v; } ): $f;
添加此内容后,使用all
调用true
完全没问题。
答案 0 :(得分:3)
最好传递一个函数来将值映射到布尔值,然后可以将其缩减为最终值。
function all($map, $data) {
if (empty($data)) { return false; }
$reduce = function($f, $n) {
return $f && $n;
};
return array_reduce(array_map($map, $data), $reduce, true);
}
$gte0 = function($v) { return $v >= 0; };
$gte2 = function($v) { return $v >= 2; };
$data = array(1, 2, 3, 4, 5);
var_dump(all($gte0, $data));
var_dump(all($gte2, $data));
然后该函数的结果仍然是预期的,但可以根据需要插入测试。您可以更进一步,允许传递map和reduce函数。
function mr($map, $reduce, $data) {
return array_reduce(array_map($map, $data), $reduce, true);
}
答案 1 :(得分:3)
intval
可以做你正在寻找的东西(特别是因为数组在你的例子中只包含整数):
var_dump(all('intval', $test)); // False
但是,many types to integer conversions are undefined in PHP和浮点数会向零舍入,所以这可能不是你想要的。
更正确的“函数”将与布尔值true相反:empty
,但它不是函数,因此您不能使用它(并反转返回值):
var_dump(!all('empty', $test)); // Does not work!
PHP中没有名为boolval
或类似的函数,所以如果需要,请自行编写;)
此外,您的all
功能可以进行优化。在迭代时,如果当前结果已经是FALSE
,则最终结果将始终为FALSE
。无论如何也无需拨打$f()
n * 2
次:
function all($f, array $arr)
{
$result = (bool) $arr;
foreach($arr as $v) if (!$f($v)) return FALSE;
return $result;
}
编辑: knittl is right指向array_filter
,它转换为布尔值,没有给出任何函数,因为没有“boolval”函数,所以看起来很酷:
function all($f, array $arr)
{
return ($c = count($arr))
&& ($f ? $arr = array_map($f, $arr) : 1)
&& $c === count(array_filter($arr));
}
var_dump(all(0, $test)); // False
使第一个函数参数成为可选项,可以通过array_filter
对每个数组元素进行适当的bool强制转换。
答案 2 :(得分:2)
您可以使用PHP的array_filter
功能,它会删除所有&#39; falsy&#39;如果未指定回调,则从数组中获取值:
$a = array ( true, true, false );
var_dump($a == array_filter($a));
答案 3 :(得分:1)
PHP中没有任何true()函数,您应该将该值与true进行比较。
试
return ($f === $v1) && ($f === $v2);
而不是
return $f($v1) && $f($v2);
答案 4 :(得分:0)
我认为这应该有效:
function all($f, array $arr)
{
return empty($arr) ? false : array_reduce($arr, function($v1, $v2) use ($f) {
return $f($v1) && $f($v2);
}, true);
}
function isTrue($a)
{
return true === $a;
}
all("isTrue", $test);