2010-08-24 4 views
22

Comment vérifier qu'un tableau ne contient que des valeurs qui sont des entiers? Je voudrais pouvoir vérifier un tableau et finir avec une valeur booléenne de true si le tableau contient seulement des entiers et false s'il y a d'autres caractères dans le tableau. Je sais que je peux boucle à travers le réseau et vérifier chaque élément individuellement et retourner true ou false en fonction de la présence de données non numérique:Plus de manière concise de vérifier si un tableau ne contient que des nombres (entiers)

Par exemple:

$only_integers = array(1,2,3,4,5,6,7,8,9,10); 
$letters_and_numbers = array('a',1,'b',2,'c',3); 

function arrayHasOnlyInts($array) 
{ 
    foreach ($array as $value) 
    { 
     if (!is_int($value)) // there are several ways to do this 
     { 
      return false; 
     } 
    } 
    return true; 
} 

$has_only_ints = arrayHasOnlyInts($only_integers); // true 
$has_only_ints = arrayHasOnlyInts($letters_and_numbers); // false 

Mais est-il une façon plus concise Pour ce faire, utilisez des fonctionnalités PHP natives auxquelles je n'ai pas pensé?

Note: Pour ma tâche actuelle, je n'aurai besoin que de vérifier les tableaux unidimensionnels. Mais s'il y a une solution qui fonctionne récursivement, je serais reconnaissant de le voir.

+0

Est-ce que cela fonctionne également pour les non entiers? 'array ('1', '2', '3');' Je ne suis pas sûr si les éléments de formulaire sont envoyés en tant que chaîne. –

+1

Remplacez simplement is_int par is_string –

+0

Oh oui, merci! –

Répondre

42
$only_integers  === array_filter($only_integers,  'is_int'); // true 
$letters_and_numbers === array_filter($letters_and_numbers, 'is_int'); // false 

Il vous aidera à l'avenir à définir deux auxiliaires, des fonctions d'ordre supérieur:

/** 
* Tell whether all members of $array validate the $predicate. 
* 
* all(array(1, 2, 3), 'is_int'); -> true 
* all(array(1, 2, 'a'), 'is_int'); -> false 
*/ 
function all($array, $predicate) { 
    return array_filter($array, $predicate) === $array; 
} 

/** 
* Tell whether any member of $array validates the $predicate. 
* 
* any(array(1, 'a', 'b'), 'is_int'); -> true 
* any(array('a', 'b', 'c'), 'is_int'); -> false 
*/ 
function any($array, $predicate) { 
    return array_filter($array, $predicate) !== array(); 
} 
+0

Je veux juste m'assurer que je ne suis pas folle ici. Ne devrait pas $ predicate, $ array être inversé dans array_filter()? –

+0

@John vous aviez raison. J'ai beaucoup utilisé 'array_map' ces jours-ci, d'où l'erreur. –

+7

C'est ce qui arrive quand PHP n'est pas cohérent dans son ordre de paramètre .... –

4
function arrayHasOnlyInts($array) { 
    return array_reduce(
     $array, 
     function($result,$element) { 
      return is_null($result) || $result && is_int($element); 
     } 
    ); 
} 

renvoie true si le tableau ne comporte que des entiers, faux si au moins un élément n'est pas un nombre entier et null si le tableau est vide.

4

Il y a toujours array_reduce():

array_reduce($array, function($a, $b) { return $a && is_int($b); }, true); 

Mais je serais en faveur de la solution la plus rapide (qui est ce que vous avez fourni) sur la plus concise.

+0

Pour favoriser la solution la plus rapide. – shamittomar

+0

La question est, comment savez-vous quel est le plus rapide sans benchmarking? –

+0

le code OP court-circuit l'itération en renvoyant false si l'un des éléments n'est pas entier. le reste des solutions proposées itère sur l'ensemble du tableau. – stillstanding

7
<?php 
$only_integers = array(1,2,3,4,5,6,7,8,9,10); 
$letters_and_numbers = array('a',1,'b',2,'c',3); 

function arrayHasOnlyInts($array){ 
    $test = implode('',$array); 
    return is_numeric($test); 
} 

echo "numbers:". $has_only_ints = arrayHasOnlyInts($only_integers)."<br />"; // true 
echo "letters:". $has_only_ints = arrayHasOnlyInts($letters_and_numbers)."<br />"; // false 
echo 'goodbye'; 
?> 
+3

+1 pour une solution simple, mais cela ne fonctionnera pas avec les grandes baies. – alexn

+0

que se passe-t-il avec de grandes baies que cela ne fonctionnera pas? – mcgrailm

+0

Si l'entier produit par implode() est plus grand que la valeur max du serveur, il échouera. –

5

Une autre alternative, mais probablement plus lent que d'autres solutions affichées ici:

function arrayHasOnlyInts($arr) { 
    $nonints = preg_grep('/\D/', $arr); // returns array of elements with non-ints 
    return(count($nonints) == 0); // if array has 0 elements, there's no non-ints 
} 
+0

Fonctionne si les valeurs sont des entiers mais de type chaîne par ex. '" 123 "'. Vous pouvez le simplifier à '$ only_integers === preg_grep ('/ \ d /', $ only_integers); // true' comme dans la réponse de @Ionut G. Stan. – xofer

0

Pourquoi donnons-nous pas aller à des exceptions?

Prendre une fonction de tableau intégrée qui accepte un rappel d'utilisateur (array_filter(), array_walk(), même en triant des fonctions comme usort() etc.) et lancer une exception dans le rappel. Par exemple. pour les tableaux multidimensionnels:

function arrayHasOnlyInts($array) 
{ 
    if (! count($array)) { 
     return false; 
    } 

    try { 
     array_walk_recursive($array, function ($value) { 
      if (! is_int($value)) { 
       throw new InvalidArgumentException('Not int'); 
      } 

      return true; 
     }); 
    } catch (InvalidArgumentException $e) { 
     return false; 
    } 

    return true; 
} 

Ce n'est certainement pas le plus concis, mais un moyen polyvalent.

Questions connexes