开发者

More concise way to check to see if an array contains only numbers (integers)

开发者 https://www.devze.com 2023-01-13 12:07 出处:网络
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 an

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.

0

精彩评论

暂无评论...
验证码 换一张
取 消