5

I have an array of values and I'd like to check that all values are either string or numeric. What is the most efficient way to do this?

Currently I'm just checking for strings so I was just doing if (array_filter($arr, 'is_string') === $arr) which seems to be working.

7 Answers 7

8

See: PHP's is_string() and is_numeric() functions.

Combined with array_filter, you can then compare the two arrays to see if they are equal.

function isStringOrNumeric($in) {
// Return true if $in is either a string or numeric
   return is_string($in) || is_numeric($in);
}

class Test{}

$a = array( 'one', 2, 'three', new Test());
$b = array_filter($a, 'isStringOrNumeric');

if($b === $a)
    echo('Success!');
else
    echo('Fail!');
Sign up to request clarification or add additional context in comments.

5 Comments

Would be great if he needed to have data on each field individually, but quite inefficient when you just need one value for whole array, isn't it?
My apologies, read the question wrong. I have updated it to use the array_filter, but I still think this solution will iterate through the array twice (but I believe is unavoidable)
I understand the logic of your function, but I think lots of programmers forgot "old ways" to think in procedural way and with sequence approach to things. Take a look at my answer, honestly tell me what don't you like about it.
Absolutely nothing, it's a perfectly valid solution.
I don't understand your (his) solution, why trying to use array_filter and compare whole array O(2n) when you can have O(n) without any problems... I don't mean to troll or insult you I just want to understand what's better on your way and reason why you choose this way (or whether you just wanted to change his code as little as possible).
7

More effective would be this:

function isStringNumberArray( $array){
  foreach( $array as $val){
    if( !is_string( $val) && !is_numeric( $val)){
      return false;
    }
  }
  return true;
}

This method:

  • won't create new array
  • will stop after first invalid value

Comments

3

If you're looking to do a single run through the array, you could write your own function to check each of the values against your specific criteria. Something like:

function is_string_or_numeric($var)
{
    return is_string($var) || is_numeric($var);
}

Then you can filter your array like:

if (array_filter($arr, 'is_string_or_numeric') === $arr)

Comments

2

PHP's ctype functions, specifically ctype_alpha() and ctype_digit() are also worth looking at:

http://php.net/manual/en/book.ctype.php

Comments

0

Well, it really depends on what you mean by "either string or numeric" (this could mean is_numeric(X), or is_int(X) || is_string(X), or any number of other things). Probably the most efficient way (though it's more verbose) is this:

public function isValid(array $array) {
    $valid = TRUE;

    foreach ($arr as $value) {
        if (!is_int($value) && !is_string($value)) {
            $valid = FALSE;
            break;
        }
    }

    return $valid;
}

Comments

0

Lots of answers for this one. If you want to use the method you've been using, you will want to write your own function for this.

so for each element in the array you are going to check if it is a number:

function isNumber($array_element) {
    return is_numeric($array_element);
}

and then call that test function using array_filter

if (array_filter($arr, 'is_number')  {
  // is a number code here.
}

Have you written a function 'is_string()'? If not, array_filter($arr, 'is_string') may not be working the way you think it is.).

2 Comments

Wouldn't you acheive the same thing with less code if you just ran if(array_filter($arr, 'is_numeric') instead of creating a new function.
Seems off-topic to me
0

Two facts:

  • foreach is faster than array_map(), because it doesnt call a function on each iteration
  • using the === Operator is faster than is_int / is_string, like so:

    if ((int)$value === $value) echo "its an int";

    if ((string)$value === $value) echo "its a string";

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.