I am trying to change multidimensional array index in running foreach:
$array = array(
array("apple", "orange"),
array("carrot", "potato")
);
$counter = 0;
foreach($array[$counter] as &$item) {
echo $item . " - ";
$counter = 1;
}
I supposed, that output would be apple - carrot - potato -, because in first run it takes value from zero array and then in next runs values from first array.
However, the output is apple - orange -
I tried add "&" before variable $item, but i guess it is not what I am looking for.
Is there any way to do it?
Thank you
// Well, i will try to make it cleaner:
This foreach takes values from $array[0], but in run i want to change index to 1, so in next repeat it will take values from $array[1]
Is that clear enough?
Note: I do not know how many dimensions my array has.
My purpose of this is not to solve this exact case, all I need to know is if is it possible to change source of foreach loop in run:
My foreach
$counter = 0;
foreach($array[$counter] as $item) {
echo $item . " - ";
}
is getting values from $array[0] right now. But inside it, I want to change $counter to 1, so next time it repeats, it will get values from $array[1]
$counter = 0;
foreach($array[$counter] as $item) {
echo $item . " - ";
$counter = 1;
}
I see, it is kind of hard to explain. This is how foreach should work:
Index of $array is $counter
First run
$array[0] -> as $item = apple
echo apple
wait, now counter changes to 1
Second run
$array[1] -> as $item = carrot
echo carrot
Third run
$array[1] -> as $item = potato
echo potato
END
I am really trying to make it clear as much as possible :D
When foreach first starts executing, the internal array pointer is automatically reset to the first element of the array. Now, by changing counter, you are changing the array (the inside one), but it is set to the first array again.
Changing the array in between may result in unexpected behaviour.
Source: Foreach: PHP.net
So finally, I found a time for this, and this is how you can change index of source array in running loop.
Thanks to you, I realized, that i can not do this by foreach, but there are many other loops.
If you were facing the same problem, here is my solution:
$array = array(
array("apple", "orange"),
array("carrot", "potato")
);
$counter = 0;
$x = 0;
while($x < count($array[$counter])) {
echo $array[$counter][$x] . " - ";
$x++;
if($counter == 0) {
$x = 0;
$counter = 1;
}
}
And the output is: apple - carrot - potato - as I wanted to achieve.
Related
I'm having trouble understanding how the foreach loop works in this code. My understanding is that $Score is assigned the arrays of $Die1 + $Die2, but how does $Score gain the value of 1,2,3,4,5,6,5,4,3,2,1? Shouldn't it be 1,2,3,4,5,6,1,2,3,4,5,6 in a sequence since that's how the values are listed in the $FaceValues array? Is there something that's happening in the foreach statements that I'm missing? Can anyone could elaborate on the double foreach statements here?
$FaceValues = array(1, 2, 3, 4, 5, 6);
$ScoreCount = array();
for($PossibleRolls = 2; $PossibleRolls <= 12; ++$PossibleRolls){
$ScoreCount[$PossibleRolls] = 0;
}
foreach ($FaceValues as $Die1) {
foreach ($FaceValues as $Die2) {
// all possible combinations
++$RollCount;
// increment RollCount
$Score = $Die1 + $Die2;
// 1,2,3,4,5,6
// 6,5,4,3,2,1
++$ScoreCount[$Score];
}
}
foreach ($ScoreCount as $ScoreValue => $ScoreTimes){
echo "<p> A combined value of $ScoreValue occured $ScoreTimes of $RollCount times. </p>";
}
On the first iteration $Die1 is 1 and $Die2 is 2. So it begins at 2 and goes up to 7. Then the inner loop is finished and the outer loop proceeds to set $Die1 to 2. You should then see the number 3 through 8.
You can use echo or var_dump() and exit() to print the values at each step and stop if you're having trouble following-along.
I have an array $scripts_stack = []; that holds arrays:
$array_item = array('script' => $file_parts, 'handle' => $file_name, 'src' => $url);
array_push($scripts_stack, $array_item);
<?php
for ($i = 0; $i < sizeof($scripts_stack); $i++) {
$child_array = $scripts_stack[$i];
if (is_array($child_array)) {
// Do things with $child_array,
// then remove the child array from $scripts_stack when done with (BELOW)
unset($scripts_stack[$i]);
}
}
echo "Array Size : " . (sizeof($scripts_stack)); // AT THE END
However, my attemts only remove half the elements. No matter what I try, it's only half the items that get removed. sizeof($scripts_stack) is always half the size of what it was at the start.
I'm expecting that it would be empty // AT THE END
Why is it that I only get half the elements in the array removed?
Thank you all in advance.
As mentioned in other answers, $i increments but the sizeof() the array shrinks. foreach() is probably the most flexible looping for arrays as it exposes the actual key (instead of hoping it starts at 0 and increments by 1) and the value:
foreach ($scripts_stack as $key => $child_array) {
if (is_array($child_array)) {
// Do things with $child_array,
// then remove the child array from $scripts_stack when done with (BELOW)
unset($scripts_stack[$key]);
}
}
Just FYI, the way you're doing it with for almost works. You just need to establish the count before the loop definition, rather than recounting in the continuation condition.
$count = sizeof($scripts_stack);
for ($i = 0; $i < $count; $i++) { // ...
Still, I think it would be better to just use a different type of loop as shown in the other answers. I'd personally go for foreach since it should always iterate every element even if some indexes aren't present. (With the way you're building the array, it looks like the indexes should always be sequential, though.)
Another possibility is to shift elements off of the array rather than explicitly unsetting them.
while ($child_array = array_shift($scripts_stack)) {
// Do things with $child_array,
}
This will definitely remove every element from the array, though. It looks like $child_array should always be an array, so the is_array($child_array) may not be necessary, but if there's more to it that we're not seeing here, and there are some non-array elements that you need to keep, then this won't work.
You advanced $i while the array is getting shrinked, but in the same time you jump over items in your array.
The first loop is where $i == 0, and then when you removed item 0 in your array, the item that was in the second place has moved to the first place, and your $i == (so you will not remove the item in the current first place, and so on.
What you can do is use while instead of for loop:
<?php
$i = 0;
while ($i < sizeof($scripts_stack)) {
$child_array = $scripts_stack[$i];
if (is_array($child_array)) {
// Do things with $child_array,
// then remove the child array from $scripts_stack when done with (BELOW)
unset($scripts_stack[$i]);
} else {
$i++;
}
}
echo "Array Size : " . (sizeof($scripts_stack)); // AT THE END
May be you can use this script.It's not tested.
foreach($array as $key => $value ) {
unset($array[$key]);
echo $value." element is deleted from your array</br>";
}
I hope , it will help you.
The problem root is in comparing $i with sizeof($scripts_stack). Every step further sizeof($scripts_stack) becomes lower (it calculates at every step) and $i becomes higher.
The workaround may look like this:
<?php
$scripts_stack = [];
$array_item = array('script' => 1, 'handle' => 2, 'src' => 3);
array_push($scripts_stack, $array_item);
array_push($scripts_stack, $array_item);
array_push($scripts_stack, $array_item);
array_push($scripts_stack, $array_item);
array_push($scripts_stack, $array_item);
while (sizeof($scripts_stack) > 0) {
$child_array = array_shift($scripts_stack);
if (is_array($child_array)) {
// Do things with $child_array,
// then remove the child array from $scripts_stack when done with (BELOW)
}
}
echo "Array Size : " . (sizeof($scripts_stack)); // AT THE END
https://3v4l.org/N2p3v
This is a part of my PHP program.
//for example: $rec_count = 30
$totalpages=(int)$rec_count/10;
$index=0;
$pageslink[$totalpages]='';
while($index <= $totalpages ){
$pageslink['index']=$index;
echo '<br>Index: '.$index.'<br>';
echo '<br>Page '.$pageslink['index'].' ';
$index++;
}
print_r($pageslink);
It comes out like this:
Index: 0
Page 0
Index: 1
Page 1
Index: 2
Page 2
Index: 3
Page 3 Array ( [3] => [index] => 3 )
Its supposed to be pageslink[0] = 1; pageslink[1 ]= 2; pageslink[3] = 3; But When I print_r() the pageslink array , only 3 as a value. I've been trying to find out why only 3 is inserted as value in array.
I am a beginner, so thank you in advance for your help. It will be much appreciated.
In the short version of this answer, arrays in PHP start counting from 0, not 1. So on the first loop it would be 0 and the second loop it would be 1 and so on.
You're using
$pageslink['index'] = $index;
Meaning you set the item with the named key 'index' in your array to the value of your variable $index, instead of using $index as your key.
In PHP (and many other languages) you can refer to an item in an array with its index number (0, 1, 2, etc.) or by a word (named key).
For example:
$myArray = ['John', 'London'];
echo $myArray[0]; // John
echo $myAray[1]; // London
or
$myArray = ['name' => 'John', 'city' => 'london'];
echo $myArray['name']; // John
echo $myArray['city']; // London
What you are doing now is setting the same item in your array (the item you're calling index) to a new value every loop, overwriting its old value. So after all the loops you'll only have the last value saved.
You want something like this:
$pageslink[$index] = $index + 1;
Which will translate to:
$pageslink[0] = 1; // first loop
$pageslink[1] = 2; // second loop
$pageslink[2] = 3; // third loop
By the way, a for loop would be cleaner in your example code:
$rec_count = 30
$totalpages=(int)$rec_count/10;
$pageslink = array(); // this is how to create an array, not with ''
for($i=0;i<$totalpages;$i++){
$pageslink[] = $i;
}
print_r($pageslink);
You over complicate the code here, try:
$totalpages=(int)$rec_count/10;
$index=0;
$pageslink = array();
while($index <= $totalpages ){
$pageslink[]=$index+1;
echo '<br>Index: '.$index.'<br>';
echo '<br>Page '.$pageslink[$index].' ';
$index++;
}
print_r($pageslink);
But this code is very weird. You just create array of n elements.
Could you explain what do you try to achieve here?
<?php
$i = $_GET['i'];
echo $i;
$values = array();
while ($i > 0)
{
$expense = $_GET['expense_' + i];
$amount = $_GET['amount_' + i];
$values[$expense] = $amount;
i--;
print_r($values);
}
?>
i represents the number of sets of variables I have that have been passed through from the previous page. What I'm trying to do is add the expenses to the amounts and put them in an array as (lets just say for this example there were 3 expenses and 3 amounts) [expense_3 => amount_3, expense_2 => amount_2, expense_1 => amount_1]. The names of the variables are successfully passed through via the url as amount_1=50, amount_2=50, expense_1=food, expense2=gas, etc... as well as $i, I just dont know how to add those variables to an array each time.
Right now with this code I'm getting
4
Array ( [] => ) Array ( [] => ) Array ( [] => ) Array ( [] => )
I apologize if I'm not being clear enough, but I am pretty inexperienced with PHP.
The syntax error you're getting is because you're using i instead of $i - however - that can be resolved easily.
What you're looking to do is "simple" and can be accomplished with string-concatenation. It looks like you're attempting this with $_GET['expense'] + i, but not quite correct.
To properly build the parameter name, you'll want something like $_GET['expense_' . $i], here you can see to concatenate strings you use the . operator - not the + one.
I'm going to switch your logic to use a for loop instead of a while loop for my example:
$values = array();
for ($i = $_GET['i']; $i > 0; $i--) {
$expense = $_GET['expense_' . $i];
$amount = $_GET['amount_' . $i];
$values[$expense] = $amount;
}
print_r($values);
This is following your original logic, but it will effectively reverse the variables (counting from $i down to 1). If you want to count up, you can change your for loop to:
$numVariables = $_GET['i'];
for ($index = 1; $index <= $numVariables; $index++) {
$expense = $_GET['expense_' . $index];
...
Or just serialize the array and pass it to the next site, where you unserialize the array
would be much easier ;)
$xml = simplexml_load_file($xmlPath);
$items = $xml->list->item;
...
echo $items[$currentIndex]->asXML();
When I print out $currentIndex on each iteration, I get 0, 1, 2, 3, 4, etc.
When I hard code $items[0]->asXML(); $items[1]->asXML(); $items[2]->asXML(); etc. I get the data I want.
But when I loop like I do in the first code segment, it prints out items 0, 2, 4, etc.
How is that possible and what could be causing this?
Thanks,
Ryan
ADDED INFO:
This is the main part of it:
$totalItems = 45;
$keepItems = 10;
$currentIndex = 0;
while($totalItems > $keepItems)
{
$totalItems -= 1;
print_r($xml->list->item[$currentIndex]);
$currentIndex += 1;
}
I just tried this in a separate file and it worked in that instance:
$xml = simplexml_load_file($xmlPath);
$items = $xml->list->item;
$counter = 45;
$display = 0;
while($counter > 4)
{
echo $items[$display]->asXML();
$display += 1;
$counter -= 1;
}
So something in my other code is making this happen. I will have to look at it some more as well, but it's for sure nothing obvious.
Thanks,
Ryan
ADDED INFO 2:
OK, I determined the line of code that causes this "every other one" syndrome :)
unset($items[$currentIndex]);
The thought was to remove/unset an item once I used the data, but it doesn't seem to work the way I expected -- does anybody have an idea of why? Why is it unsetting something it hasn't displayed?
Thanks,
Ryan
Why is it unsetting something it hasn't displayed? That's not what is happening in your case. When you unset the processed item, the array-data are shift... the former element at index 1 get the index 0, 2 moves to 1 and so on. So if you access $element[1] after you have unset $element[0] you'll get the element that was at position $element[2], because the former $element[1] moved to $element[0] and $element[2] to $element[1].
If you always unset the processed element, you can do it by accessing $element[0] on each iteration an cancel if the array is empty.
// ...
while ($array) { // same as count($array)
$currentElement = $array[0];
// do something
unset($array[0]);
}
// ...