tags:

views:

78

answers:

4

I have a simple associative array:

$ar = array( 1=>'foo', 2=>'bar', 5=>'foobar', 8=>'barfoo' )

I need to efficiently find holes in the keys. The keys are guaranteed to be integers.

findHole($ar)
> 0
findHole($ar,1)
> 3

findHole($ar,5)
> 6

what is the easiest way to do this?

+9  A: 

Try this:

function findHole($array, $key=0) {
    while (array_key_exists($key, $array)) {
        $key++;
    }
    return $key;
}
Gumbo
+1  A: 

All holes:

function GetHoles($arr)
{
    $holes = array();

    $max_value = max(array_keys($arr));
    for($i = 0; $i < $max_value; $i++)
    {
        if(!in_array($i, $keys)) $holes[] = $i;
    }

    return $holes;
}
Stefan K
+2  A: 

The desired behavior of your findHole function isn't 100% clear to me, but the following code snippet will give you an array that has all the "missing" indexes.

$ar = array( 1=>'foo', 2=>'bar', 5=>'foobar', 8=>'barfoo' );
$keys = array_keys($ar);
$missing_indexes = array_diff(range(0,max($keys)), $keys);
print_r($missing_indexes);

Depending on your use case this may or may not be less efficient. It's using multiple function calls and arrays are passed around by value by default, but those functions are operating at native code speeds, while solutions using loops are going to be running at PHP speed.

Use case, benchmark, etc.

Alan Storm
A: 

if you just want to condense the array, try this:

function FlattenArray( $o ) 
{ 
    $res = array(); 
    foreach($o as $v) 
    { 
        $res = array_merge($res, FlattenArray($v)); 
    } 
    return $res; 
}
TravisO