How can I convert this into a loop in PHP?
$number = 4; // This number is unknown and can be any number.
if ($number === 1) {
echo $red;
} else if ($number === 2) {
echo $yellow;
} else if ($number === 3) {
echo $orange;
} else if ($number === 4) {
echo $black;
} else if ($number === 5) {
echo $green;
} else if ($number === 6) {
echo $grey;
} else if ($number === 7) {
echo $brown;
} else if ($number === 8) {
echo $blue;
} else if ($number === 9) {
echo $silver;
} else if ($number === 10) {
echo $gold;
} else if ($number === 11) {
echo $white;
}
etc...
Right now the $number can be any number, so I would have to somehow loop through the numbers from 1 to unlimited, until it finds what $number is equal to. In this case, number is equal to 4.
I'm not sure why you want to do it like this, but:
$i = 1;
while ($i !== $number) {
$i++;
}
$int = $i;
To do what you want, you should use an array map, but an switch might do the trick too.
PHP don't actually know 1 = one, so you can't iterate through it with a loop.
You have to provide this mapping to it, be it by switching instead of loads of ifs, or creating an array map.
Why not just create a array of items that are the 'lookup table' in the order need like:
$items = ['item_1', 'item_2', 'item_3', … 'item_n'];
or have a string of items like:
$items = explode('|', 'item_1|item_2|item_3|item_n');
//| being the delemiter or what ever might not occur inside any items
then have your $number (might need to minus 1 to $number if items start with 1 and so on to get correct item) used in the array to get the specific item without a loop like:
//$number = 3
$number--;
echo $items[$number];//echos 'item3'
but it almost seems like you then want something like:
//$number = 3
$items = explode('|', 'red|pink|gold|invisible');
echo ${$items[$number - 1]};
//translates into `echo $gold;`
//echos whatever is in $gold
Reading some of your comments it seems like you might be best off to rethink your logic/variables and use arrays and such instead of possibly hundreds of differently named variables that you have to check every time which can't be converted into a simple loop like you wish it could be. The only other possibly is using variables variables like many, including me, have mentioned but you seem to shoot them down. I wouldn't recommend variables variables personally but it would possibly speed up time without needing to do any looping. To effectively minimize code without the need of many if/elses you need to have logic that is consistent.
I think this is what you mean :
echo ${"file" . $number};
But that is showing variable for $filen, for example : $file1, file2, etc. If you want to make it as number, you can do like this :
echo ${"file" . intToEnglish($number)};
You can make intToEnglish(int $number) yourself or need us for help?
I'm not quite sure why you need to loop this, but if you really need to loop this, you can try this :
$i = 0;
while ($i !== $number) {
$i++;
}
echo ${"file" . intToEnglish($i)};
But, make sure that echo ${"file" . intToEnglish($number)}; is exist or you will go through infinite looping.
-- EDIT --
This is the case with your edited colour variable case. If you want to make it simple (looping), you muse change how your variable assingned. Example :
$colour = array("green","yellow","red","blue","black");
$i = 0;
while ($i !== $number) {
$i++;
}
echo $colour[$i];
Actually that looping is not really necessary until you have process inside it. You can just define it directly like this :
echo $colour[number];
-- EDIT 2 ---
This is with checking things :
while($i <= $number) {
if($i === $number) { echo $colour[number]; }
else { echo 'Checking'. $i; }
}
Loop is completly the wrong construct for your problem.
Use an array like so:
<?php
$number = 2;
$english = array("zero","one","two","three","four");
echo "file" . $english[$number];
?>
displays filetwo
After OP edit all becomes clear -- try:-
<?php
$number = 2;
$red = "crimson";
$clear = "glass";
$yellows = array("gold","lemon","acid","ochre");
$orange = "tangerine";
$black = "charcoal";
$objects = array(&$clear,&$red,&$yellows,&$orange,&$black);
var_dump( $objects[$number] );
?>
outputs:
array(4) { [0]=> string(4) "gold" [1]=> string(5) "lemon" [2]=> string(4) "acid" [3]=> string(5) "ochre" }
Related
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!
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) ? " REPEAT\n" : "\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 REPEAT\n or \n by itself if it isn't.
echo ($repeat) ? " REPEAT\n" : "\n";
The whole line...
echo $current_point . (($repeat) ? " REPEAT\n" : "\n");
...then outputs the $current_point followed by either REPEAT\n or \n.
I'm not 100% if I understand correctly your desired outcome, but here are the problems I see:
You keep redefining $NewArray in the Previous function, so every time you run it, the array will become empty. You have to put that variable outside the function, and refer to it with the global scope. I also renamed it to $previousLocations. Here is the new function:
$previousLocations = array();
function Previous (string $x, string $y)
{
global $previousLocations;
$Location = $x . '.' . $y;
echo "<br>";
if(in_array($Location, $previousLocations)) {
// Already visited location
echo "Revisiting: " . $Location;
} else {
$previousLocations[] = $Location;
echo $Location;
}
}
Output:
1.0
2.0
2.1
2.2
1.2
Revisiting: 2.2
3.2
Please correct me if I misunderstood something.
I'm trying to find the number of strings that satisfy some conditions in a foreach loop. This is what I've tried so far:
<?php
$list = $item->getProperty();
$n = 0;
foreach($list as $single) {
$designation = $single->getPropertyName(); // var_dump($designation); outputs 150 strings
if (strpos($designation, 'foo') === 0) { // var_dump($designation); outputs 5 strings containing 'foo' in their designation names
$n++;
echo count($n);
}
}
?>
echo count($n); returns 11111 instead of returning 5 which is the value I want to obtain.
Could someone help me out a bit?
<?php
$list = $item->getProperty();
$n = 0;
foreach($list as $single) {
$designation = $single->getPropertyName(); // var_dump($designation); outputs 150 strings
if (strpos($designation, 'foo') === 0) { // var_dump($designation); outputs 5 strings containing 'foo' in their designation names
$n++;
}
}
echo $n;
If you would like to achieve the same in a more functional and elegant way, you could use array_reduce
array_reduce($item->getProperty(), function($sum, $single) {
if (strpos($single->getPropertyName(), 'foo') === 0) {
$sum++;
}
return $sum;
});
A less readable, but more elegant one-line solution would look like:
array_reduce($item->getProperty(), function($sum, $single) { return (strpos($single->getPropertyName(), 'foo') === 0) ? ++$sum : $sum; }
And now that we have short arrow functions in PHP, you can use this if you are running on PHP 7.4:
array_reduce($item->getProperty(),
fn($sum, $single) => (strpos($single->getPropertyName(), 'foo') === 0) ? ++$sum : $sum);
I have an array and I need to find if the values are even or odd and print them.
$numbers = [1,2,3,4,5,6,7,8,9,10,11,12,13,14];
And I print the results in array format (I`m looking to use "echo" to print each)
I found a solution that is to create a while loop and use modules %2
like:
$foreach ($numbers % 2==0) { //even
echo "value is even";
} else {
echo "value is odd";
}
But it doesnt work, and i only have experience working with numbers in if statements and loops. How would i go about this when working with an array.
Thanks in advance.
Welcome to Stackoverflow.
$numbers = [1,2,3,4,5,6,7,8,9,10,11,12,13,14];
foreach ($numbers as $n) {
echo 'value '. $n .' is: ';
echo ($n % 2 == 0) ? 'even' : 'odd';
echo "\n"; // optional
}
You can try also like this, this is more understandable for you
$numbers = [1,2,3,4,5,6,7,8,9,10,11,12,13,14];
foreach($numbers as $value)
{
if($value%2==0)
{
echo $value 'is even <br/>';
}
else
{
echo $value 'is odd <br/>';
}
}
Here is the code,
You are in right direction but there will be a little bit of change in your code i.e. you are applying condition on whole array which is wrong you have to fetch single value and apply even number condition.
$numbers = [1,2,3,4,5,6,7,8,9,10,11,12,13,14];
foreach($numbers as $var)
{
if($var%2==0)
{
echo $var;
}
else
{
echo $var;
}
}
I can't figure out how to test if there's a next item in my array by using the key to test against. I think this is better explained in code. I know there's an easier way, I'm just a noob!
Basically I want to know if there is another item in the array and if so get the ->comp_id value.
for($i=0; $i<count($allcomps); $i++)
{
if($allcomps[$i]->comp_id == $curCompID)
{
$currentIndex = $i;
if($allcomps[$i+1]->comp_id == null )
{
echo "there isn't a next";
}
//echo $allcomps[$currentIndex+1]->comp_id;
}
}
You're already looping through allcomps, so why do you need a check for the next one?
Why not check within the loop?
for($i=0; $i<count($allcomps); $i++) {
if (isset($allcomps[$i]->comp_id) and $allcomps[$i]->comp_id == $curCompID) {
$currentIndex = $i;
}
}
I think a foreach might be even easier:
foreach($allcomps as $i=>$comp) {
if (isset($comp->comp_id) and $comp->comp_id == $curCompID) {
$currentIndex = $i;
}
}
I'm trying to display only the names that are not empty from this array on a new line for each. Currently, using this, it is only displaying "$playerName1"'s name 10 times. I'm trying to figure out why it's not actually looping through all 10 playerName's. It seems to only be checking $playerName1.
$z = array($playerName1, $playerName2, $playerName3, $playerName4, $playerName5, $playerName6, $playerName7, $playerName8, $playerName9, $playerName10);
$zCounter = 1;
foreach ($z as $allNames) {
while ($allNames != "" && $zCounter < 11) {
echo $allNames . "<br>";
$zCounter++;
}
}
Your problem is that you are going through the inner while loop for only the first player name. The outer foreach loop should be plenty:
foreach ($z as $playerName) {
if ("" !== $playerName) {
echo $playerName . "<br />";
}
}
Unless you want to output each name 10 times, remove the while loop. You can still check to make sure the name is not empty by using !='' or empty()
<?php
$z = array($playerName1, $playerName2, $playerName3, $playerName4, $playerName5, $playerName6, $playerName7, $playerName8, $playerName9, $playerName10);
foreach($z as $name){
if(!empty($name)){
echo $name.'<br>';
}
}
you need to reset the $zCounter after each while loop
foreach ($z as $allNames) {
while ($allNames != "" && $zCounter < 11) {
echo $allNames . "<br>";
$zCounter++;
}
$zCounter = 0;
}
otherwise after the first while loop finishes, $zCounter will always be 11