Is there a way to get the the current position of an array from within a nested array ?
I have a php script that has a for loop which cycles through an array, with in this is an nested loop which cycle through a sub array.
I can use pos() to get the position of the child array, is there anyway of getting the current position of the parent array.
I am sure there must be a way to do this, or is the best way to just create a counter?
thanks in advance
.k
If you're using a for loop, you already have a counter. In this example, it's $i :
for($i = 0; $i < $arrayLength; $i++) ...
If you're actually using a foreach loop, use the syntax that gives you the key:
foreach($array as $key => $value) ...
A PHP variable has no information from where it is referenced - due to references and copy-on-write there might be even more things (global/local variables, array elements, properties, ...) pointing to a single variables.
If you have a reference to the "parent" element you can use pos() on that, if not you have to handle this yourself.
Related
I'm using an array and a for loop in PHP and it works well without any problem, but I want to improve the performance and speed of the script.
This is my script (PHP) :
$data=[1,2,3,4=>[1,2]];
for ($i=0; $i < count($data); $i++) {
if(is_array($data[$i]){
//do something
}
}
As you can see it will check the whole array to detect if array has sub array or not and the thing which I want to know is - is there anyway to filter this array and send the filtered sub arrays to foreach? I mean just use elements which have a sub array, like $data[4] which has this sub array : [1,2] (which I'm currently checking by using is_array in if(is_array($data[$i]){).
If the array was like this: $data=[1,2,3,4,5,6,7,8,9,10=>[1,2],11,12,13,14,15=>[1,2]]; it would take more time to find only 2 useful elements (10 and 15) and others (1 to 9 and 11 to 14) are useless, I want to skip them before I use them on foreach.
I'm not looking for a way to do it manually inside my existing loop, I'm looking for a built-in function which would be optimized for speed and performance.
Thanks a lot.
Get all elements that is an array:
$data = array_filter($data, "is_array");
Get all elements that is not an array:
$data = array_filter($data, fn($e) => !is_array($e));
I have an a problem I know how to tackle it but not 100% clear on what the implementation would look like.
This is a Symfony 3 app but the problem is a pure PHP one which involves some kind of recursion.
I have a multi-dimensional array which represents my nested form and and an errors that need to be mapped to a form field (that bit I know how to do).
Here is my array:
I need to loop over the children of fields recursively and when I reach the end of a node and it contains message key (just a way to confirm I have reached the error) then apply that to the form // apply to form here then remove that index/node so that the recursion doesn't go down that route again?
Can anyone help with the function that will do this. Like I said it is not important to know Symfony just help with the function that will recurs a mutli-dimensional array and remove that node before calling itself again.
My class at it stands but I can cut atleast 50% of this if I can just follow the array keys:
http://laravel.io/bin/ok5n9
Any help will be greatly appreciated :)
When looping through your array, use a for loop so you can easily manipulate indexes:
for($i = 0; $i < count($fields); $i++) {
// You can use $fields[$i] here for the current item
}
Using isset(), you can check if the message key exists in the fields array. If that is true, use the continue keyword to skip over the current item and continue with the next one.
It will look something like this, you can change it according to your needs:
for($i = 0; $i < count($fields); $i++) {
if (isset($fields[$i]['message')) {
// error exists...
continue;
}
// Delete the item from your array
unset($fields[$i]);
}
This is my fix. I created a form map which consists of the number of fields each with child arrays for the path to the element and the error.
I then loop over them and pass them through Symfonys mapViolation method in Symfony\Component\Form\Extension\Validator\ViolationMapper\ViolationMapper.
Here is complete class:
https://gist.github.com/linxlad/3ec76c181f717fba532bf43484b7c970
I would like to take the first value in an array and use it within a function. Then, I would like to repeat the function using the second value in the array. This should make use of count(); so that it stops once it reaches the end of the array. This seems simple enough, but I have no idea how to move to the next array value without writing a separate function. Quick Googling yielded something about for, but I'm not sure what to make of it.
Most basic PHP tutorials would have shown you this language construct. But, for the sake of being friendly, PHP includes multiple ways to iterate over an array and perform an action. Consider the following:
function writeArrayItem($item) {
echo $item . '<br>';
}
$array = [1, 2, 3];
foreach ($array as $item) {
writeArrayItem($item);
}
We create a simple little function that takes a value and ECHO's it back out. Then we instantiate an array object with three values, 1, 2 and 3.
After this, we use PHP's FOREACH iterator to loop over each value in the array, casting that value into the variable $item. Within the loop, we call the function we previously declared, and hand it the value we want it to echo out.
There are other loop constructs you could use, but FOREACH is a very helpful tool when you want to iterate over each value in an array.
If you must (for school purposes) make use of count(), then a FOR loop would be your choice. Use the same function above, and change the foreach to this FOR code:
for ($i = 0; $i < count($array); $i++) {
writeArrayItem($array[$i]);
}
The change here is we have to manually track the index in the array and use it to retrieve the value. We also use the number of items in the array to predicate how many loop cycles we will have. Because arrays are zero-based indexes, your starting value is usually 0, and you want to loop to the number of items in the array minus 1.
In this case we use:
$i < count($array)
Once $i reaches 2, the loop will stop because we are saying to loop while $i is smaller than count($array) which equals 3, and because on a zero-based index, array[2] is actually the third index as the first index is array[0];
Hope all that helps!
what is the best way to access all the elements of the object instead of using foreach?
Thanks in advance...
get_object_vars — Gets the properties of the given object
details - http://php.net/manual/en/function.get-object-vars.php
What's wrong with foreach?
Well but there are several methods
You could do something like:
$length = count($arr);
for($i = 0; $i<$length; $i++)
you could also do
while($i < $length)
and access the items directly if you do have numeric keys.
However foreach won't be slower and its the best way to go if you don't have numeric keys.
You can also access the items using next($arr) or you can push/pop
I would say it depends on the context what you want to do.
If you want to do X operations with an array of size X for example you need some loop.
If yuo only want to apply the very same operation on all elements you can use the handy function array_map
if you just want to get all information from it you could also use get_object_vars however, then you have just a new array and what then?
It really depends on the context what you want to do!
In most cases foreach is fine and fast.
If you want to search for specific keys/values or see whether they exists, there are special optimized array functions for that,.
I'm trying to look through an array of records (staff members), in this loop, I call a function which returns another array of records (appointments for each staff member).
foreach($staffmembers as $staffmember)
{
$staffmember['appointments'] = get_staffmember_appointments_for_day($staffmember);
// print_r($staffmember['appointments'] works fine
}
This is working OK, however, later on in the script, I need to loop through the records again, this time making use of the appointment arrays, however they are unavailable.
foreach ($staffmembers as $staffmember)
{
//do some other stuff
//print_r($staffmember['appointments'] no longer does anything
}
Normally, I would perform the function from the first loop, within the second, however this loop is already nested within two others, which would cause the same sql query to be run 168 times.
Can anyone suggest a workaround?
Any advice would be greatly appreciated.
Thanks
foreach iterates over a copy of the array. If you want to change the value, you need to reference it:
foreach($staffmembers as &$staffmember) // <-- note the &
{
$staffmember['appointments'] = get_staffmember_appointments_for_day($staffmember);
// print_r($staffmember['appointments'] works fine
}
From the documentation:
Note: Unless the array is referenced, foreach operates on a copy of the specified array and not the array itself. foreach has some side effects on the array pointer. Don't rely on the array pointer during or after the foreach without resetting it.
and
As of PHP 5, you can easily modify array's elements by preceding $value with &. This will assign reference instead of copying the value.