views:

68

answers:

3

Is there a function which I could give an array, which would return true if the provided function returned true for all of them?

theFunction(array(1,2,3) , 'is_numeric') //true
theFunction(array(1,"b",3) , 'is_numeric') //false
+3  A: 

No, but you can use array_reduce:

array_reduce(array(1,2,3),
    function ($a, $v) { return $a && is_numeric($v); }, true);

You can of course build your own higher-order function:

function for_all(array $arr, $func) {
    return array_reduce($arr,
        function ($a, $v) use ($func) {
            return $a && call_user_func($func, $v);
        }, true);
}

var_dump(
    for_all(array(1,2,3), 'is_numeric')
); //true
Artefacto
@Artefacto is your avatar one of the default ones?
quantumSoup
@quantum Yes, it is. I got used to it.
Artefacto
Compatibility note: anonymous functions only work on PHP >= 5.3.0
quantumSoup
+2  A: 
 /**
  * all in collection?
  *
  * Passes each element of the collection to the given function. The method
  * returns true if the function never returns false or null.
  * 
  * If the function is not given, an implicit
  * function ($v) { return ($v !== null && $v !== false) is added
  * (that is all() will return true only if none of the collection members are false or null.)
  *
  * @param array $arr input array
  * @param function $lambda takes an element, returns a bool (optional)
  * @return boolean
  */
 function all($arr, $lambda=null) {
     // these differ from PHP's "falsy" values
     if (!is_callable($lambda)) {
         foreach ($arr as $value)
             if ($value === false || $value === null)
                 return false;
     } else {
         foreach ($arr as $value)
             if (!call_user_func($lambda, $value))
                 return false;
     }
     return true;
 }

This is lifted from my implementation of Ruby's enum

You can call it like:

var_dump(all($array, 'is_numeric'));
var_dump(all($array, 'is_string'));
var_dump(all($array, function($x) { return $x != 'fun';})); // PHP >= 5.3.0
quantumSoup
+1  A: 

If you don't mind about efficiency and care more about simplicity you can use the min and array_map without having to create new functions.

(bool)min(array_map('is_numeric', array(1,2,3))); //true
(bool)min(array_map('is_numeric', array(1,"b",3))); //false

Also if you think about the process as finding one that doesn't fit the pattern you can rewrite it a bit cleaner.

!array_filter('is_not_numeric', array(1,2,3)); //true
!array_filter('is_not_numeric', array(1,"b",3)); //true
Kendall Hopkins