Apologies for the dumb question, I just can't seem to understand what's exactly going on. I have a JS function which I transformed into PHP and in the JS everything is working as desired.
The problem with the PHP one is here I believe:
I have last element of and array which I get by
$lastPeriod = end($periods);
while being in a for loop.
Next I set the value of $lastPeriod['closeTime'] to equal a number. If I dd($lastPeriod) after changing it's value it is updated, however if I dd(); at the end it is not. Maybe there is a conflict with how I remove the next element so the end is not working correctly?
for ( $i = 0; $i < sizeof($dailyHours); $i++ )
{
$periods = $dailyHours[$i]['periods'];
for ($j = 0; $j < sizeof($periods); $j++)
{
$lastPeriod = end($periods);
if ($lastPeriod['closeTime'] === '00:00'
&& $dailyHours[$i + 1]['periods'][0]['openTime'] === '00:00'
&& $dailyHours[$i + 1]['periods'][0]['closeTime'] !== '00:00')
{
if (Carbon::parse($dailyHours[$i + 1]['periods'][0]['closeTime'])->isBefore(Carbon::createFromTimeString('11:59')))
{
$lastPeriod['closeTime'] = $dailyHours[$i + 1]['periods'][0]['closeTime'];
array_splice($dailyHours[$i + 1]['periods'], 0, 1);
if (sizeof($dailyHours[$i + 1]['periods']) < 1)
{
$dailyHours[$i + 1]['isOpen'] = 0;
}
}
}
}
}
}
The problem is that you are editing a copy of the array.
Let's look at this example:
<?php
$myPets = [
[
'animal' => 'cat',
'name' => 'john'
],
];
$pet = $myPets[0];
$pet['name'] = 'NewName';
var_dump($myPets);
When I run this program the name of my pet should be 'NewName' right?
array(1) {
[0]=>
array(2) {
["animal"]=>
string(3) "cat"
["name"]=>
string(4) "john"
}
}
Well, as you can see the name hasn't changed.
This is because when we do $pet = $myPets[0] PHP will make a copy of the $myPets[0] array.
To fix this you can take the reference of that array by doing:
$pet = &$myPets[0].
There are a few issues in the code:
In a loop you have this code:
$lastPeriod = end($periods);
Then later on you have:
$lastPeriod['closeTime'] = $dailyHours[$i + 1]['periods'][0]['closeTime'];
This should result in a warning
Warning: Cannot use a scalar value as an array in ....
The issue that $lastPeriod = end($periods); gives you the value of the last element in the array. So if you have this array:
$dailyHours[0]['periods'][] = 23;
$dailyHours[0]['periods'][] = 12;
$dailyHours[0]['periods'][] = 5;
$dailyHours[0]['periods'][] = 8; //Last elements value in item 0
$dailyHours[1]['periods'][] = 23;
$dailyHours[1]['periods'][] = 11;
$dailyHours[1]['periods'][] = 3; //Last elements value in item 1
$dailyHours[2]['periods'][] = 5;
$dailyHours[2]['periods'][] = 12; //Last elements value in item 2
Therefore
$lastPeriod = end($periods);
would return the values 8,3 and 12.
A simplified version of your code with two loops. The outer loop ($i) and the inner loop ($j)
for ( $i = 0; $i < sizeof($dailyHours); $i++ ) {
$periods = $dailyHours[$i]['periods'];
for ($j = 0; $j < sizeof($periods); $j++) {
$lastPeriod = end($periods); //would give 8,8,8, 3,3,3 and 12,12,12
//This would basically mean that an associative array with key closeTime
//with the value of 8,3 or 12 => is the same as the value of $dailyHours[$i +
//1]['periods'][0]['closeTime'];
//This is not a thing PHP can handle and therefore you should reviece
//a warning "Cannot use a scalar value as an array..."
//(You simply cannot mix numbers and associative arrays in that manner)
$lastPeriod['closeTime'] = $dailyHours[$i + 1]['periods'][0]['closeTime'];
}
}
Another issue is that you're trying to set a value each iteration with the same key and therefore nothing happens:
for ( $i = 0; $i < sizeof($dailyHours); $i++ ) {
$periods = $dailyHours[$i]['periods'];
for ($j = 0; $j < sizeof($periods); $j++) {
$lastPeriod['closeTime'] = rand();
echo '<pre>';
echo $lastPeriod['closeTime'];
echo '</pre>';
}
}
A possible output of the loops above code could be:
1393399136
1902598834
1291208498
654759779
493592124
1469938839
929450793
325654698
291088712
$lastPeriod['closeTime'] would be 291088712 which is the last set value above (last iteration) but the previous values set are not stored anywhere.
Related
I'm trying to create for loop giving strings empty value. How I can do it?
for ($i = 1; $i <= 24; $i++) {
$b2_ch_v = ${'b2_g_v_'.$i}['id'];
$$b2_ch_v = '';
}
/*
result should be:
$b2_g_v_1['id'] = '';
$b2_g_v_2['id'] = '';
[...]
$b2_g_v_24['id'] = '';
*/
Don't use variables named like $x1, $x2, $x3. You almost always want to use arrays instead. In this case, you can use an indexed array of associative arrays. This is sometimes also called a two-dimensional array.
for ($i = 0; $i < 24; $i++) {
$b2_ch_v[$i] = ['id' => ''];
}
Then your first element becomes:
$b2_ch_v[0]
And its named elements can be referred to via:
$b2_ch_v[0]['id']
You're setting $b2_ch_v to the current contents of the id element of the array, not a reference to the array element. You need to refer to the array index in the assignment.
for ($i = 1; $i <= 24; $i++) {
$b2_ch_v = 'b2_g_v_'.$i;
${$b2_ch_v}['id'] = '';
}
var_dump($b2_g_v_1); // => array(1) { ["id"]=> string(0) "" }
You don't actually need the variable, you can do the calculation in the assignment:
${'b2_g_v_'.$i}['id'] = '';
But it's best to avoid variable variables in the first place, and use arrays instead as in the other answer.
I have implemented the following small example:
$nodeList;
for($i = 0; $i < 10;$i++) {
$nodeList[$i] = $i;
for($j = 0; $j < 3;$j++) {
$nodeList[$i][$j] = $j;
}
}
foreach($nodeList[0] as $nodeEl) {
print "NodeEl: ".$nodeEl." | ";
}
print nl2br("\n\r");
$testList = array
(
array(1,2,3),
array(4,5,6),
array(7,8,9),
array(10,11,12),
);
foreach($testList[0] as $testEl) {
print "TestEl: ".$testEl." | ";
}
Where the output for $nodeList is null (var_dump / print_r too) and the output for $testList is TestEl: 1 | TestEl: 2 | TestEl: 3, as expected.
In my understanding those two solutions should create roughly the same output - but instead there is no output for the first one at all. Because the second dimension of the array is not even created.
Reading up on http://php.net/manual/de/language.types.array.php creates the strong feeling that the [] operator is only for dereferencing / accessing of the array, but then again the docs provide a sample where they assign a value to a certain key the same way I do $arr["x"] = 42.
What is the difference between these two ways of array access?
How can I achieve filling a n-dimensional array in a way similar to the way I try to fill $nodeList?
You should make sure to have error reporting turned on, because warnings are generated for your code:
E_WARNING : type 2 -- Cannot use a scalar value as an array -- at line 7
This concerns the following statement:
$nodeList[$i] = $i;
If you want to create a 2D array, there is no meaning in assigning a number on the first level. Instead you want $nodeList[$i] to be an array. PHP does that implicitely (creating the array) when you access it with brackets [...], so you can just leave out the offending statement, and do:
for($i = 0; $i < 10;$i++) {
for($j = 0; $j < 3;$j++) {
$nodeList[$i][$j] = $j;
}
}
You can even leave out the $j in the last bracket pair, which means PHP will just add to the array using the next available numerical index:
for($i = 0; $i < 10;$i++) {
for($j = 0; $j < 3;$j++) {
$nodeList[$i][] = $j;
}
}
Adding a value at every level
If you really need to store $i at the first level of the 2D array, then consider using a more complex structure where each element is an associative array with two keys: one for the value and another for the nested array:
for($i = 0; $i < 10; $i++) {
$nodeList[$i] = array(
"value" => $i,
"children" => array()
);
for($j = 0; $j < 3;$j++) {
$nodeList[$i]["children"][] = array(
"value" => "$i.$j" // just example of value, could be just $j
);
}
}
$nodeList will be like this then:
array (
array (
'value' => 0,
'children' => array (
array ('value' => '0.0'),
array ('value' => '0.1'),
array ('value' => '0.2'),
),
),
array (
'value' => 1,
'children' => array (
array ('value' => '1.0'),
array ('value' => '1.1'),
array ('value' => '1.2'),
),
),
//...etc
);
You should write
<?php
$nodeList;
for($i = 0; $i < 10;$i++) {
for($j = 0; $j < 3;$j++) {
$nodeList[$i][$j] = $j;
}
}
foreach($nodeList[0] as $nodeEl) {
print "NodeEl: ".$nodeEl." | ";
}
You need to declare $nodeList as array like
$nodeList=array();
and for 2D array
$nodeList= array(array());
I want to sum each row of a multidimensional array :
$number = array
(
array(0.3,0.67, 0.3),
array(0.3,0.5,1),
array(0.67,0.67,0.3),
array(1,0.3,0.5)
);
The result what i want is like this :
row1 = 1.27
row2 = 1.8
row3 = 1.64
row4 = 1.8
I already tried this code :
for($i = 0; $i < 4; $i++) {
for($j = 0; $j < 5; $j++) {
$sumresult[] = array_sum($number[$i][$j]);
}
}
But it appear an error like this :
Warning: array_sum() expects parameter 1 to be array, double given in xxxx
array_sum needs array not values. Do like this:
for($i = 0; $i < 4; $i++) {
$sumresult[] = array_sum($number[$i]);
}
its because you are passing an value instead of the array containing it.
One correct solution would be:
$sumResult = array();
foreach($number as $values){
$sumResult []= array_sum($values);
}
print_r($sumResult);
Should do the trick ;)
It's easier to just map the array_sum() function to the array to sum the inner arrays:
$sumresult = array_map('array_sum', $number);
I've had this problem a few times now when for looping over an array item.
In this instance I'm generating all 2 letter combinations of the alphabet.
The code works (and I know there's a much easier way of doing it with 2 for loops, but I'm trying something different).
However I have to do count -1 as count() returns the number 26 for the array length, however the 26th item obviously doesn't exist as it's 0 based?
Is there not a version of count() that works on a zero-based basis?
<?php
$alphas = range('a', 'z');
$alphacount = count($alphas);
// Why do I have to do this bit here?
$alphaminus = $alphacount -1;
$a = 0;
for ($i=0;$i<$alphacount;$i++) {
$first = $alphas[$a];
$second = $alphas[$i];
if ($i === $alphaminus && $a < $alphaminus ) {
$i = 0;
$a ++;
}
echo "$first$second<br>";
}
?>
Without $alphaminus = $alphacount -1; I get undefined offset 26?
How about:
<?php
$alphas = range('a', 'z');
$alphacount = count($alphas);
$a = 0;
for ($i=0;$i<$alphacount;$i++) {
$first = $alphas[$a];
$second = $alphas[$i];
if ($i >= $alphacount && $a < $alphaminus ) {
$i = 0;
$a ++;
}
echo "$first$second<br>";
}
So you don't have to to -1 since you don't like it! :)
And how about:
$alphas = range('a', 'z');
for ($i = 0; $i < count($alphas); $i++) {
for ($a = 0; $a < count($alphas); $a++) {
echo "{$alphas[$i]}{$alphas[$a]}\n";
}
}
Or forget about arrays! This is more fun :)
array_walk($alphas, function ($a) use ($alphas) {
array_walk($alphas, function ($b) use ($a) {
print "$a$b\n";
});
});
The problem is that you reset $i to 0 in the loop; then on encountering the end of the loop $i is incremented, so the next run in the loop will be with $i = 1 instead of $i = 0.
That is, the next subrange of letters starts with (letter)b instead of (letter)a. (See your output: the next line after az is bb rather than ba.)
Solution: reset $i to -1 in the loop, then at the end it will run with the value 0 again.
You have 26 characters, but arrays in PHP are indexed from 0. So, indexes are 0, 1, ... 25.
count is 1-based and arrays created by range() are 0-based.
It means that:
$alphas[0] == a
$alphas[25] == z
$count($alphas) = 26; // there are 26 elements. First element is $alphas[0]
Why does it have to be so complicated? You could simply do
foreach ($alphas as $alpha)
{
foreach($alphas as $alpha2)
{
echo $alpha.$alpha2."<br>";
}
}
Note: It is mostly not a good idea to manipulate the loop counter variable inside the body of that very loop. You set $i to 0 on a certain condition. That could give you unexpected results, hence the reason why you have to navigate around it.
say I have an array
$test_backwards=array("something1","something2","something3");
this is just a testing example and it's important to note that values will be added dinamically in my final array. so is it possible to dynamically return values from behind, namely starting from the last element?
something like this but backwards
for($i=0;$i<count($test_backwards);$i++) {
echo $test_backwards.'<br>';
}
Just start at the end and decrement your index:
for ($i = count($test_backwards) - 1; $i >= 0; $i--) {
echo $test_backwards[$i].'<br>';
}
or use array_reverse() (slower):
$test_backwards = array_reverse($test_backwards);
for ($i = 0; $i < count($test_backwards); $i++) {
echo $test_backwards[$i].'<br>';
}
You can also use array_pop(), if you do not need to keep this array. Or you can assign it to a temp array and then array_pop it, it will get and delete value from last.
$temp = $test_backwards;
while(($item = array_pop($temp)) !== NULL ) {
echo $item;
}