Pregunta

¿Es posible utilizar array_map () para poner a prueba los valores de una matriz? Quiero para asegurarse de que todos los elementos de una matriz son numéricos.

He intentado tanto

$arrays = array(
         array(0,1,2,3 )
        , array ( 0,1, "a", 5 )
);

foreach ( $arrays as $arr ) {

        if ( array_map("is_numeric", $arr) === FALSE ) {
                echo "FALSE\n";
        } else {
                echo "TRUE\n";
        }
}

y

$arrays = array(
         array(0,1,2,3 )
        , array ( 0,1, "a", 5 )
);

foreach ( $arrays as $arr ) {

        if ( ( array_map("is_numeric", $arr) ) === FALSE ) {
                echo "FALSE\n";
        } else {
                echo "TRUE\n";
        }
}

Y por tanto consigo

TRUE
TRUE

Puede hacerse esto? Si es así, ¿qué estoy haciendo mal?

Nota: Soy consciente de que puedo conseguir mi funcionalidad deseada a partir de un bucle foreach

.
¿Fue útil?

Solución

array_map devuelve una matriz. Por lo que siempre será considerado 'verdadero'. Ahora, si array_search para FALSO, usted podría ser capaz de obtener los efectos deseo.

Desde el PHP.net Página

array_map() returns an array containing all the elements of 
arr1 after applying the callback function to each one.

Esto significa que en la actualidad tiene una matriz que contiene verdadero o falso para cada elemento. Usted tendría que utilizar array_search(false,$array) para averiguar si hay algún falsos valores.

Otros consejos

Normalmente soy un gran defensor de array_map(), array_filter(), etc., pero en este caso foreach() va a ser la mejor opción. La razón es que con array_map() y otros que pasará a través de toda la matriz no importa qué. Pero para sus propósitos sólo tiene que ir a través de la matriz hasta que se encuentra con un valor para el cual is_numeric() devuelve falso, y por lo que yo sé no hay manera en PHP para salir de esos métodos.

En otras palabras, si usted tiene 1.000 artículos en su matriz y el quinto no es numérico, utilizando array_map() todavía comprobar los valores restantes 995 a pesar de que ya conoce la matriz no pasa la prueba. Sin embargo, si utiliza un foreach () en su lugar y tienen que break en is_numeric() == false, entonces usted sólo tiene que comprobar los primeros cinco elementos.

Se puede usar el filtro, pero termina con un poco horrible código

$isAllNumeric = count(array_filter($arr, "is_numeric")) === count($arr)

El uso de una función personalizada hace que sea un poco mejor, pero todavía no es perfecto

$isAllNumeric = count(array_filter($arr, function($x){return !is_numeric($x);})) === 0

Pero si estuviera utilizando funciones personalizadas array_reduce quiere trabajar, pero todavía tiene algunos fallos.

$isAllNumeric = array_reduce($arr,
                             function($x, $y){ return $x && is_numeric($y); },
                             true);

Los defectos son que no se romperá cuando se ha encontrado lo que quiere, por lo que las sugerencias funcionales anteriores no son muy eficientes. Usted tendría que escribir una función como esta:

function array_find(array $array, $callback){
    foreach ($array as $x){ //using iteration as PHP fails at recursion
        if ( call_user_func($callback, array($x)) ){
            return $x;
        }
    }
    return false;
}

Y usarlo como tal

$isAllNumeric = array_find($arr, function($x){return !is_numeric($x);})) !== false;

tengo dos funciones pequeñas pero muy útiles en mi "biblioteca estándar"

function any($ary, $func) {
   foreach($ary as $val)
      if(call_user_func($func, $val)) return true;
   return false;
}

function all($ary, $func) {
   foreach($ary as $val)
      if(!call_user_func($func, $val)) return false;
   return true;
}

en su ejemplo

 foreach ( $arrays as $arr )
    echo all($arr, 'is_numeric') ? "ok" : "not ok";

Un enfoque más elegante en mi humilde opinión

foreach ($arrays as $array)
{
 if (array_product(array_map('is_numeric', $array)) == true)
 {
  echo "TRUE\n";
 }

 else
 {
  echo "FALSE\n";
 }
}

Esto devolverá verdadero si todos los valores son numéricos y falso si alguno de los valores no es numérico.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top