I have an array as follows
$array[$id][$iterator][test1][test2][a][b][c][d]
I would like to test for each $iterator for the first instance of test1=not null (if so use a, b, c d)
else use the first instance of test2=not null use (a, b, c, d)
else use "---"
I don't know how to get a loop to break on first instance of a finding test1 and test2 or if there is a better construct to use than a loop in this case?
To break an iteration or loop
Just tell it to take a break :)
foreach ($array as $item) {
if ($item == 'I the great overlord command you to stop iterating!') {
break;
}
}
If you wanna...
if you just want to know if a certain value is in your array, you can do it like this:
if (in_array('The value you are looking for', $thatArrayItShouldBeIn)) {
die("Its in! Its in! Yippie!");
}
From the comments
Tell me if I'm wrong, but from your comment I come to understand you want your iteration to break at a certain loop?
foreach ($array as $key => $item) {
// Keys start at 0, so the first item is 0
if ($key == 3) {
// We'll stop looping at the 4th iteration
break;
}
}
Taking yet another look
If you really have an array with alot of layers and you just want to check one value for each iteration you can just do:
foreach ($array[$id]['iterator'] as $item) {
if ($item['test1'] == true) {
// Do something
}
} }
Related
I'm attempting to compare non-matching values within two multidimensional arrays ($allSessions, my master array and $userSessions, my inner array...everything in it should be within $allSessions, but structured differently) and my approach was to use a foreach within a foreach loop.
This works under most situations except one (when $userSession only contains one item).
I'm wondering if the bug is caused by this loop within a loop? When it is buggy because $userSessions only contains 1 item, the returned $unregistered array contains multiples of each item...
$allSessions = $this->getAllUpcoming();
$unregistered = array();
$userSessions = $this->getUserSessions($userID);
foreach ($allSessions as $session) {
foreach ($userSessions as $user) {
if ($user["entry_data"]["session-participant-session"]["id"] !== $session["id"]){
array_push($unregistered, $session);
}
}
}
In the way you have it, you will get every non-matching element.
Let's say you have a perfect match of a,b,c in $allSessions and a,b,c in $userSessions. In your first outer loop you have 'a'. In the inner loop you will add 'b' and 'c' to your $unregistered because they don't match. Then you go on to 'b' in your outer loop and add 'a' and another copy of 'c' in your inner loop. And so on.
I'm pretty you're going to have to structure it differently. You've got to check every element in $userSessions and go on to the next element in $allSessions only if you don't find any matches:
foreach ($allSessions as $session) {
foreach ($userSessions as $user) {
if ($user["entry_data"]["session-participant-session"]["id"] === $session["id"])
continue 2; // this goes to the next element in $allSessions
}
array_push($unregistered, $session);
}
A slightly more readable form if you are not familiar with continue:
foreach ($allSessions as $session) {
$found = false;
foreach ($userSessions as $user) {
if ($user["entry_data"]["session-participant-session"]["id"] === $session["id"]) {
$found = true;
break; // an optimization - not strictly necessary
}
}
if (!$found)
array_push($unregistered, $session);
}
I have an array such which lists a number of options for a menu and then in each of those options another array of suboptions.
In one display I want to check the key of one of the top options i.e 'useroptions' and if I find that, I want to skip over that whole subarray and move onto the next one. I'm having a problem at the moment though I have this code, but it shows the last suboption
if($item->key=='useroptions' {
$item = $item->children->last();
}
I would have thought something like
$item = $item->sibling->next();
but this isn't working.. Can anyone show me the correct way please.
Thanks
Wheelz
Check this example:
$arr = array(1, 2, 3, 4);
foreach ($arr as &$value) {
switch($value) {
case 3:
echo '<p>Skipped the number 3</p>';
break 1;
default:
break;
}
}
?>
Or this one:
foreach ( $array as $value ) {
if ( $value == 3 )
continue; # Skips
# Code goes here...
}
if($item->key != 'useroptions') {
// Do something using subarray
}
You can use the php function next() to advance to the next pointer in array.
next($array)
http://php.net/manual/en/function.next.php
if that if is inside a loop then do this it might help :
if($item->key=='useroptions') {
continue;
}
I am returning an array of values using mysql_fetch_array.
In the while loop, i need to perform an if condition on the next element of the array.
E.g
if next($row) == 'test'
{
...
}
The thing is 'next($row)' is returning me the index of the next element in the array. I would like to test for the next $row("name").
if next($row("name")) == 'test'
{
...
} //this code is incorrect
Is there a way of doing this in php?
Thanks a lot for your help :)
if the "next($row)" gives you the index of the next cell in the array then just use it to perform the test. $arr[next($row)] = the next cell value/obj/whatever you have there
foreach ($rows as $k => $row) {
if (isset($rows[$k+1]) && $rows[$k+1] == 'test') //do something
// Do normal stuff here
}
I want to loop through an array with foreach to check if a value exists. If the value does exist, I want to delete the element which contains it.
I have the following code:
foreach($display_related_tags as $tag_name) {
if($tag_name == $found_tag['name']) {
// Delete element
}
}
I don't know how to delete the element once the value is found. How do I delete it?
I have to use foreach for this problem. There are probably alternatives to foreach, and you are welcome to share them.
If you also get the key, you can delete that item like this:
foreach ($display_related_tags as $key => $tag_name) {
if($tag_name == $found_tag['name']) {
unset($display_related_tags[$key]);
}
}
A better solution is to use the array_filter function:
$display_related_tags =
array_filter($display_related_tags, function($e) use($found_tag){
return $e != $found_tag['name'];
});
As the php documentation reads:
As foreach relies on the internal array pointer in PHP 5, changing it within the loop may lead to unexpected behavior.
In PHP 7, foreach does not use the internal array pointer.
foreach($display_related_tags as $key => $tag_name)
{
if($tag_name == $found_tag['name'])
unset($display_related_tags[$key];
}
Instead of doing foreach() loop on the array, it would be faster to use array_search() to find the proper key. On small arrays, I would go with foreach for better readibility, but for bigger arrays, or often executed code, this should be a bit more optimal:
$result=array_search($unwantedValue,$array,true);
if($result !== false) {
unset($array[$result]);
}
The strict comparsion operator !== is needed, because array_search() can return 0 as the index of the $unwantedValue.
Also, the above example will remove just the first value $unwantedValue, if the $unwantedValue can occur more then once in the $array, You should use array_keys(), to find all of them:
$result=array_keys($array,$unwantedValue,true)
foreach($result as $key) {
unset($array[$key]);
}
Check http://php.net/manual/en/function.array-search.php for more information.
if you have scenario in which you have to remove more then one values from the foreach array in this case you have to pass value by reference in for each:
I try to explain this scenario:
foreach ($manSkuQty as $man_sku => &$man_qty) {
foreach ($manufacturerSkus as $key1 => $val1) {
// some processing here and unset first loops entries
// here dont include again for next iterations
if(some condition)
unset($manSkuQty[$key1]);
}
}
}
in second loop you want to unset first loops entries dont come again in the iteration for performance purpose or else then unset from memory as well because in memory they present and will come in iterations.
There are already answers which are giving light on how to unset. Rather than repeating code in all your classes make function like below and use it in code whenever required. In business logic, sometimes you don't want to expose some properties. Please see below one liner call to remove
public static function removeKeysFromAssociativeArray($associativeArray, $keysToUnset)
{
if (empty($associativeArray) || empty($keysToUnset))
return array();
foreach ($associativeArray as $key => $arr) {
if (!is_array($arr)) {
continue;
}
foreach ($keysToUnset as $keyToUnset) {
if (array_key_exists($keyToUnset, $arr)) {
unset($arr[$keyToUnset]);
}
}
$associativeArray[$key] = $arr;
}
return $associativeArray;
}
Call like:
removeKeysFromAssociativeArray($arrValues, $keysToRemove);
I want to do something like this:
foreach ($array as $key=>$value except when $key="id")
{
// whatever
}
... without having to put an "if" clause inside the body of the loop. It is not guaranteed that "id" will the be the first or last element in the array, and I don't really want to unset or slice the array, because that will be expensive, ugly, and not maintain the original data. I also definitely need to use both key and value inside the loop.
Any ideas?
I don't think that the if-clause is such a problem:
foreach ($array as $key => $value) {
if ($key == 'ignore_me') continue;
if ($key == 'ignore_me_2') continue;
If you want a fancy solution, you can use array_diff_key:
$loop_array = array_diff_key($actual_array, array('ignore_me' => NULL, 'ignore_me_2' => NULL));
foreach ($loop_array as $key => $value) {
#...
Go with the if-clause inside the loop.
There is nothing inelegant about it, it is the easiest to read and understand, and it is the most efficient.
If you have many keys to skip you could build a second hash to test against (in the if-clause):
foreach ($array as $key => $value) {
if (array_key_exists($key,$skip_keys)) continue;
...
}
I think you'll always end up to use an IF clause in the inner loop. Of all the options you already gave, that's the only one I would use for the speed and the memory consumption
AFAIK you can't do it without an if in the loop.
Like the keyword says, it's "for each", not "for most".
EDIT: like soulmerge says, you could do it with array_diff_key(), but if you're only missing out a single key it's more verbose and less memory efficient than just putting the if in the loop.
Another way of compacting the if statement is:
// ignore 1,5,8,9
foreach($arr as $key){
if(in_array($key, array(1,5,8,9)) continue;
...
}