views:

368

answers:

5

I have this function:

function coin_matrix($test, $revs) {
    $coin = array();

    for ($i = 0; $i < count($test); $i++) {
        foreach ($revs as $j => $rev) {
            foreach ($revs as $k => $rev) {
            if ($j != $k && 
                $test[$i][$j] != null && 
                $test[$i][$k] != null) {

                $coin[$test[$i][$j]][$test[$i][$k]] += 1 / ($some_var - 1);
                }
            }
        }
    }
    return $coin;
}

where

$test = array(
array('3'=>'1','5'=>'1'),
array('3'=>'2','5'=>'2'),
array('3'=>'1','5'=>'2'),
array('3'=>'1','5'=>'1'));

and

$revs = array('3'=>'A','5'=>'B');

the problem is that when I run it, it returns these errors (notices):

Notice: Undefined index: 1 at line 10

Notice: Undefined index: 1 at line 10

Notice: Undefined index: 2 at line 10

Notice: Undefined index: 2 at line 10

Notice: Undefined index: 2 at line 10

Notice: Undefined index: 1 at line 10

which is this line: $coin[$test[$i][$j]][$test[$i][$k]] += 1 / ($some_var - 1);

The problem is that at the end the function returns the correct matrix (array) and if I test to see if $coin[$test[$i][$j]][$test[$i][$k]] exists, then it doesn't return it anymore.

Any suggestion is greatly appreciated!

Thanks!

A: 

I don't understand much but I can suggest you to use

function coin_matrix($test, $revs) {
    $coin = array();

    for ($i = 0; $i < count($test); $i++) {
        foreach ($revs as $j => $rev) {
            foreach ($revs as $k => $rev) {
            if (($j != $k) && 
                ($test[$i][$j] != null) && 
                ($test[$i][$k] != null)) {

                $coin[$test[$i][$j]][$test[$i][$k]] += 1 / ($some_var - 1);
                }
            }
        }
    }
    return $coin;
}
Ronnie Chester Lynwood
+2  A: 

You can/should test to make sure that $coin[$test[$i][$j]][$test[$i][$k]] is set before incrementing the value. This shouldn't change the functionality of your code, but will make the notices go away (which is good practice).

function coin_matrix($test, $revs) {
    $coin = array();

    for ($i = 0; $i < count($test); $i++) {
        foreach ($revs as $j => $rev) {
            foreach ($revs as $k => $rev) {
            if ($j != $k && 
                $test[$i][$j] != null && 
                $test[$i][$k] != null) {

                    // new tests go here
                    if(!isset(coin[$test[$i][$j]])) 
                    {
                        coin[$test[$i][$j]] = array(); 
                    }
                    if(!isset(coin[$test[$i][$j]][$test[$i][$k]])) 
                    {
                        coin[$test[$i][$j]][$test[$i][$k]] = 0; 
                    }

                    $coin[$test[$i][$j]][$test[$i][$k]] += 1 / ($some_var - 1);
                }
            }
        }
    }
    return $coin;
}
Scott Saunders
if i do that then the function doesn't work any more. i should have mentioned that at the end it returns the right matrix (array)
Alex
How does it break? Are you sure you only set the variable if it was not set?
Scott Saunders
it returns a wrong array
Alex
ok, my mistake. it works!Thanks a lot!
Alex
I've extended the code so you can see the context. Glad to help.
Scott Saunders
+2  A: 
$coin[$test[$i][$j]][$test[$i][$k]] += 1 / ($some_var - 1);

The warning is being generated by the +=. += needs to look up the element before adding to it, and you haven't initialized any of the elements in $coin the first time you access them.

R. Bemrose
Thanks! done and it's working
Alex
+1  A: 

I think the problem is you are trying to use $coin as a two dimensional array.

if you want it to be two dimensional, $coin has to be an array of arrays.

function coin_matrix($test, $revs) {

    $coin = array();

    for ($i = 0; $i < count($test); $i++) {
        foreach ($revs as $j => $rev) {
            foreach ($revs as $k => $rev) {
            if ($j != $k && 
                $test[$i][$j] != null && 
                $test[$i][$k] != null) {
                // add this.
                if ($coin[$test[$i][$j]] == null){
                    $coin[$test[$i][$j]] = array();
                }
                // end
                $coin[$test[$i][$j]][$test[$i][$k]] += 1 / ($some_var - 1);
                }
            }
        }
    }
    return $coin;
}
coolnalu
A: 

Have you thought about swapping out the for loop with a foreach loop? Eg:

foreach( $tests as $i => $test )

This has the benefit of having a value in $test[ $i ]. Then, in your $test[ $i ][ $j ] == null block, place this:

        if ($j != $k && 
            // I suspect that this will cause errors too.
            // Do yourself a favor and add this sanity check.
            isset( $test[$j] ) && $test[$j] != null && 
            isset( $test[$k] ) && $test[$k] != null) {

                $currentK = $test[$k];
                $currentJ = $test[$j];
                // Use debug lines if setting things directly won't work
                if( !isset( $coin[ $currentJ ] ) || !is_array( $coin[ $currentJ ] ) )
                {
                    // $coin[ $currentJ ] = array();
                    die( "<pre>$currentK $currentJ \n" .  print_r( $coin ) );
                }
                $currentCoin =& $coin[ $currentJ ];
                if( !isset( $currentCoin [ $currentK ] ) || 
                    !is_array( $currentCoin [ $currentK ] ) )
                {
                    // Just curious, but when doing these checks before,
                    // did you remember to assign a numeric value here?
                    // 
                    // $currentCoin[ $currentK ] = 0;
                    die( "<pre>$currentK $currentJ \n" .  print_r( $coin ) );
                }
                $currentCoin[ $currentK ] += 1 / ($some_var - 1);
            }
        }
Christopher W. Allen-Poole