How do you verify an array contains only values that are integers?
I'd like to be able to check an array and end up with a boolean v开发者_运维技巧alue of true
if the array contains only integers and false
if there are any other characters in the array. I know I can loop through the array and check each element individually and return true
or false
depending on the presence of non-numeric data:
For example:
$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
But is there a more concise way to do this using native PHP functionality that I haven't thought of?
Note: For my current task I will only need to verify one dimensional arrays. But if there is a solution that works recursively I'd be appreciative to see that to.
$only_integers === array_filter($only_integers, 'is_int'); // true
$letters_and_numbers === array_filter($letters_and_numbers, 'is_int'); // false
It helps to define two helper, higher-order functions:
/**
* Tell whether all members of $elems validate the $predicate.
*
* all(array(), 'is_int') -> true
* all(array(1, 2, 3), 'is_int'); -> true
* all(array(1, 2, 'a'), 'is_int'); -> false
*/
function all($elems, $predicate) {
foreach ($elems as $elem) {
if (!call_user_func($predicate, $elem)) {
return false;
}
}
return true;
}
/**
* Tell whether any member of $elems validates the $predicate.
*
* any(array(), 'is_int') -> false
* any(array('a', 'b', 'c'), 'is_int'); -> false
* any(array(1, 'a', 'b'), 'is_int'); -> true
*/
function any($elems, $predicate) {
foreach ($elems as $elem) {
if (call_user_func($predicate, $elem)) {
return true;
}
}
return false;
}
<?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';
?>
Another alternative, though probably slower than other solutions posted here:
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
}
There's always array_reduce():
array_reduce($array, function($a, $b) { return $a && is_int($b); }, true);
But I would favor the fastest solution (which is what you supplied) over the most concise.
function arrayHasOnlyInts($array) {
return array_reduce(
$array,
function($result,$element) {
return is_null($result) || $result && is_int($element);
}
);
}
returns true if array has only integers, false if at least one element is not an integer, and null if array is empty.
Why don't we give a go to Exceptions?
Take any built in array function that accepts a user callback (array_filter()
, array_walk()
, even sorting functions like usort()
etc.) and throw an Exception in the callback. E.g. for multidimensional arrays:
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;
}
It's certainly not the most concise, but a versatile way.
精彩评论