So, first off. I’m a C# programmer, so my PHP code is probably strongly influenced by how you would write in C#. Anyway, I’m trying to solve a problem where I’ve got a two-dimensional grid with two axis, x and y. The user gives input, and the program will tell you your new location.
For example, if user input was ‘ >^ ‘ the location would be 1,1.
What I also want the program to do, is to tell you the first location that you revisit. So, if you go from 0,0 -> 0,1 -> 0,0 -> 1,0 -> 1,1. Then the first location you revisited was 0,0.
My problem is that I’m trying to send my int to a function and then adding it to an array, and searching the array if the array contains the object. But it seems like the array is only adding one value (?)
declare(strict_types=1); <?php $NewInput = ">>^^<>>"; $arr = str_split($NewInput, 1); $x = 0; $y = 0; Directions($x, $y, $arr); function Directions (int $x, int $y, $arr) { foreach ($arr as $item) { if ($item == '^') { $y += 1; } elseif ($item == 'v') { $y -= 1; } elseif ($item == '>') { $x += 1; } elseif ($item == '<') { $x -= 1; } Previous($x,$y); } } function Previous (string $x, string $y) { $Location = $x . '.' . $y; echo "<br>"; $NewArray = array(); $NewArray[] = $Location; $ReVisited = ""; if ($ReVisited == "") { if (array_search($Location, $NewArray)) { $ReVisited = $Location; echo $ReVisited; } } echo $Location; } ?>
What am I doing wrong? And also if you see something overall with the code that could be improved please let me know. Grateful for any tips or answers!
Advertisement
Answer
As with the other answer: The key reason your code isn’t working is because you are re-initialising $newArray
every time you call the function Previous()
and hence the array is null
.
To get around this you could use global
as @Andrew suggested.
However, your code seems a little unorganised and overly complicated… There doesn’t seem to be any need for two separate functions? The whole process is effectively one function.
If you treat it as one function then you have no need of using globals
and you can do it in far fewer lines of code!
$NewInput = ">>^^<>>"; $arr = str_split($NewInput, 1); $x = 0; $y = 0; directions($x, $y, $arr); function directions($x, $y, $arr){ $used_points = []; // Array of points which have been passed through $repeats = []; // Array of points which have been repeated foreach ($arr as $item) { switch ($item) { case '^': $y += 1; break; case 'v': $y -= 1; break; case '>': $x += 1; break; case '<': $x -= 1; break; } $current_point = "{$x}.{$y}"; $repeat = in_array($current_point, $used_points); // Checks if the point is repeated echo $current_point . (($repeat) ? " REPEATn" : "n"); // Outputs current point and whether it's a repeat $used_points[] = $current_point; // Add current point to $used_points array } } /* Output: 1.0 2.0 2.1 2.2 1.2 2.2 REPEAT 3.2 */
Additional Explanation
SWITCH
The switch
statement is effectively just another way of writing your if...elseif
statements in a way which is easier to read. Functionally it does the same job (i.e. comparing a given value against another).
The three code examples below show different ways of comparing the values. The third example is effectively what a switch
statement is.
N.B. break
is required in the switch
and while
statements to exit the statement. If you omit it then the code continues to run further down the page than you may have intended.
## Example code with switch switch ($test_case){ case 1: // Do something if $test_case == 1... break; case 2: // Do something if $test_case == 2... break; } ## Example code with if/elseif if($test_case == 1){ // Do something if $test_case == 1... } elseif($test_case == 2){ // Do something if $test_case == 2... } ## Example of if statements in a loop equivalent to switch while(TRUE){ if($test_case == 1){ // Do something if $test_case == 1... break; } if($test_case == 2){ // Do something if $test_case == 2... break; } break; }
{ curly braces } and double quotes
You can reference variables directly inside of double quotes; this often times makes code easier to read and nicer to look at. Example:
echo $a . ", " . $b . ", " . $c . ", " $d; echo "$a, $b, $c, $d";
There are however instances when doing the above can give unexpected results. The curly braces help to keep that to a minimum and is just a good practice to get into – they clearly specify which variable you mean to reference.
$current_point = "$x.$y"; // is equivalent to.... $current_point = "{$x}.{$y}";
in_array($needle, $haystack)
in_array
is simply a way to check whether or not a value is present in an array. If the value is found then the function returns TRUE
if not then FALSE
.
The line…
$repeat = in_array($current_point, $used_points);
…therefore sets $repeat
to either TRUE
or FALSE
.
Ternary Operator
The ternary operator is effectively a short hand if...else
statement.
## Example of if/else $output = ""; if($value == TRUE){ $output = 1; } else{ $output = 2; } ## Example with ternary operator $output = ($value) ? 1 : 2;
In your case we use it to check if $repeat
is TRUE
(i.e. the current coordinate is present in the already visited coordinates array). If it is TRUE
then we output REPEATn
or n
by itself if it isn’t.
echo ($repeat) ? " REPEATn" : "n";
The whole line…
echo $current_point . (($repeat) ? " REPEATn" : "n");
…then outputs the $current_point
followed by either REPEATn
or n
.