utilizzando array_map per testare i valori?
Domanda
È possibile utilizzare array_map() per testare i valori di un array?Voglio assicurarmi che tutti gli elementi di un array siano numerici.
Li ho provati entrambi
$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";
}
}
E
$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";
}
}
E per entrambi capisco
TRUE
TRUE
Può essere fatto?Se sì, cosa sto facendo di sbagliato?
Nota:Sono consapevole che posso ottenere la funzionalità desiderata da un ciclo foreach.
Soluzione
array_map restituisce un array. Così sarà sempre considerata 'vera'. Ora, se si array_search
per FALSE, si potrebbe essere in grado di ottenere gli effetti desiderio.
array_map() returns an array containing all the elements of
arr1 after applying the callback function to each one.
Questo significa che attualmente si dispone di un array che contiene vero o falso per ogni elemento. Lei avrebbe bisogno di utilizzare array_search(false,$array)
per scoprire se ci sono eventuali falsi valori.
Altri suggerimenti
Sono di solito un grande sostenitore di array_map()
, array_filter()
, ecc, ma in questo caso foreach()
sta per essere la scelta migliore. La ragione è che con array_map()
e altri che passerà attraverso l'intero array non importa quale. Ma per il tuo scopo è sufficiente passare attraverso la matrice fino a quando si esegue in un valore per il quale is_numeric()
restituisce false, e per quanto ne so non c'è modo in PHP per uscire da questi metodi.
In altre parole, se si dispone di 1.000 articoli nel tuo matrice e il 5 ° non è numerico, utilizzando array_map()
sarà ancora controllare i restanti 995 valori, anche se si conosce già la matrice non passa il test. Ma se si utilizza un foreach () al posto e lo hanno break
su is_numeric() == false
, allora avrete solo bisogno di controllare quei primi cinque elementi.
Potresti usare filter, ma finisce con un pezzo di codice orribile
$isAllNumeric = count(array_filter($arr, "is_numeric")) === count($arr)
L'uso di una funzione personalizzata lo rende un po' migliore, ma non ancora perfetto
$isAllNumeric = count(array_filter($arr, function($x){return !is_numeric($x);})) === 0
Ma se utilizzassi funzioni personalizzate array_reduce funzionerebbe, ma presenta ancora alcuni difetti.
$isAllNumeric = array_reduce($arr,
function($x, $y){ return $x && is_numeric($y); },
true);
Il difetto è che non si romperà una volta trovato ciò che vuole, quindi i suggerimenti funzionali di cui sopra non sono molto efficienti.Dovresti scrivere una funzione come questa:
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;
}
E usarlo così
$isAllNumeric = array_find($arr, function($x){return !is_numeric($x);})) !== false;
ho due funzioni molto piccole, ma estremamente utile nella mia "libreria standard"
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;
}
nel tuo esempio
foreach ( $arrays as $arr )
echo all($arr, 'is_numeric') ? "ok" : "not ok";
Un approccio più elegante IMHO :
foreach ($arrays as $array)
{
if (array_product(array_map('is_numeric', $array)) == true)
{
echo "TRUE\n";
}
else
{
echo "FALSE\n";
}
}
Ciò restituirà vero se tutti i valori sono numerici e falso se uno dei valori non è numerico.