3

Without having to change the function signature, I'd like a PHP function to behave differently if given an associative array instead of a regular array.

Note: You can assume arrays are homogenous. E.g., array(1,2,"foo" => "bar") is not accepted and can be ignored.

function my_func(Array $foo){
  if (…) {
    echo "Found associative array";
  }
  else {
    echo "Found regular array";
  }
}


my_func(array("foo" => "bar", "hello" => "world"));
# => "Found associative array"

my_func(array(1,2,3,4));
# => "Found regular array"

Is this possible with PHP?

2
  • 1
    How would this function treat arrays that contain a mixture of numeric and associative indices (array(1, 2, 'foo' => 'bar', 3, 4, 'hello' => 'world'))? Commented Aug 12, 2010 at 19:47
  • Assume arrays are homogenous; no mixtures. Commented Aug 12, 2010 at 19:48

6 Answers 6

6

Just check the type of any key:

function is_associative(array $a) {
    return is_string(key($a));
}

$a = array(1 => 0);
$a2 = array("a" => 0);

var_dump(is_associative($a)); //false
var_dump(is_associative($a2)); //true
Sign up to request clarification or add additional context in comments.

1 Comment

I like this method best. Thanks :)
2

Assuming $foo is homogeneous, just check the type of one key and that's it.

<?php

function my_func(array $foo) {
    if (!is_int(key($foo))) {
        echo 'Found associative array';
    } else {
        echo 'Found indexed array';
    }
}

?>

Comments

2

You could use a check with array_values if your arrays are small and you don't care about the overhead (if they are large, this will be quite expensive as it requires copying the entire array just for the check, then disposing of it):

if ($array === array_values($array)) {}

If you care about memory, you could do:

function isAssociative(array $array) {
    $c = count($array);
    for ($i = 0; $i < $c; $i++) {
        if (!isset($array[$i])) {
            return true;
        }
    }
    return false;
}

Note that this will be fairly slow, since it involves iteration, but it should be much more memory efficient since it doesn't require any copying of the array.

Considering your homogeneous requirement, you can simply do this:

if (isset($array[0])) {
    // Non-Associative
} else {
    // Associative
}

But note that numerics are valid keys for an associative array. I assume you're talking about an associative array with string keys (which is what the above if will handle)...

2 Comments

Regarding your edit. You can have a numeric array that doesn't have the key 0, e.g. array(1 => null)
Then it's not technically an array, it's still a hash table (and hence an associative array). Arrays would only have sequential numeric indexes from 0 to max...
0

In the light of your comment Assume arrays are homogenous; no mixtures.: Just check if first (or last, or random) key is an integer or a string.

Comments

0

This would be one way of doing it, by checking if there's any keys consisting of non-numeric values:

function my_func($arr) {
   $keys = array_keys($arr); // pull out all the keys into a new array
   $non_numeric = preg_grep('/\D/', $keys); // find any keys containing non-digits
   if (count($non_numeric) > 0) {
       return TRUE; // at least one non-numeric key, so it's not a "straight" array
   } else {
       return FALSE: // all keys are numeric, so most likely a straight array
   }
}

Comments

0
function is_associative($array) {
  return count(array_keys($array)) != array_filter(array_keys($array), 'is_numeric');
}

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.