Looping through Foreach, calling results inside of if statement - php

How can I return the data which is presented inside of this foreach element, inside of my if statement, which comes after the initial foreach.
foreach ($arr as $line) {
print $line;
}
When we print $line it should return something like this.
Example 1
Example 2
Example 3
Example 4
I want to call each element from line, to be set inside of this if statement, but only if the statement contains a specific word.
$status_check = $_GET['status'];
if (strpos($status, 'online') !== false) {
print $line; // return all of the contents from the (foreach) here.
}

Based on your comments you need to return the data of the array outside of the foreach loop so you dont need to use one.
if (strpos($_GET['status'], 'online') !== false) {
print array_values($arr);
}
Will return:
Example 1
Example 2
Example 3
Example 4
Only if $_GET['status'] contains online

Related

Iterating over one dimension of array until a value found

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
}
} }

PHP Comparing two multidimensional arrays with foreach

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);
}

How can I run 2 loops together in PHP without duplicating values?

I'm trying to check MD5 of some data with md5 some files, both of them are stored in one dimensional arrays. Say I have 4 files in the $files array with the same number of $datas, the following code prints "NO DIFFERENCE" 12 times instead of 4 times.
foreach($files as $file) {
foreach($datas as $data) {
if(md5($data) !== md5_file($file)) {
echo "NO DIFFERENCE";
}
}
}
How do I prevent duplicating a loop?
Update:
Both arrays $datas and $files contains equal number of values but the tricky part is the values in $files array starts from key number 2 (because I removed "." and ".." from scandir result) whereas in $datas array values start from key number 0.
the following code prints "NO DIFFERENCE" 12 times instead of 4 times.
The reason for that is you have a nested loop.
For each value in the $files array, your inner foreach will run once.
So say if you have 3 values in $files and 4 values in $datas, the loop will run as follows:
First value in $files iterated
Inner loop runs, and iterates through all 4 values in $datas
Second value in $files iterated
Inner loop runs, and iterates through all 4 values in $datas
Third value in $files iterated
Inner loop runs, and iterates through all 4 values in $datas
Try this with one loop like this :
foreach($datas as $key => $value) {
if(md5($value) !== md5_file($files[$key])) {
echo "NO DIFFERENCE";
}
}
Note: The loop work when you have same no of values for both arrays
If you want to compare md5(files) to the mfs5(datas) you can simply do this:
for ($i = 0; $i < sizeof($files); $i++){
if(md5($datas[$i]) !== md5_file($files[$i+2]))
echo "NO DIFFERENCE";
}
If you want to check if each file have one corresponding md5(datas) then you should use you double loop as you did.
First, are you sure that !== is the operator you want to use to say 'no difference' ?
If you are looking for equality, maybe you want to use ===
Second, md5(...) is time consuming, so extract the hash in a variable.
Third, if you mean equality, you can add a break in the inner loop to stop looping as soon as you find the equality.
foreach($files as $file) {
$md5File = md5_file($file); // extract in a variable
foreach($datas as $data) {
if(md5($data) === $md5File) { // === instead of !==
echo "NO DIFFERENCE";
break; // break as soon as possible
}
}
}
You could use a callback function. But then you should be clear about how exactly you will describe an algorithm of your problem.
The following sample shows how to maybe achieve it. But it assumes that the arrays are in the same order and that you don't want to cross-compare everything. Also array_udiff may not be the best approach for it.
function compare_by_md5($data, $file) {
if( md5($data) === md5_file($file)) {
echo "NO DIFFERENCE";
}
}
array_udiff($datas, $files, 'compare_by_md5');
Sample is shown here: http://codepad.org/lYOyCuXA
If you simply want to detect if there is a difference:
$dataHashes = array();
foreach($datas as $data) {
$dataHashes[md5($data)] = true;
}
$different = false;
foreach($files as $file) {
if(!isset($dataHashes[md5_file($file)])) {
$different = true;
break;
}
}
var_dump($different);
If you want to know which files are different, then:
$dataHashes = array();
foreach($datas as $data) {
$dataHashes[md5($data)] = true;
}
foreach($files as $file) {
if(!isset($dataHashes[md5_file($file)])) {
echo $file, 'is different', PHP_EOL;
}
}

PHP Go to the next element of array

I have created an array list with the following code:
<?php
$ids = array();
if (mysql_num_rows($query1))
{
while ($result = mysql_fetch_assoc($query1))
{
$ids["{$result['user_id']}"] = $result;
}
}
mysql_free_result($query1);
?>
Now, i need to read two elements from the array. The first is the current and the second one is the next element of array. So, the simplified process is the following:
i=0: current_element (pos:0), next_element (pos:1)
i=1: current_element (pos:1), next_element (pos:2)
etc
To do this, i have already written the following code, but i cant get the next element for each loop!
Here is the code:
if (count($ids))
{
foreach ($ids AS $id => $data)
{
$userA=$data['user_id'];
$userB=next($data['user_id']);
}
}
The message i receive is: Warning: next() expects parameter 1 to be array, string given in array.php on line X
Does anyone can help? Maybe i try to do it wrongly.
The current, next, prev, end functions work with the array itself and place a position mark on the array. If you want to use the next function, perhaps this is the code:
if (is_array($ids))
{
while(next($ids) !== FALSE) // make sure you still got a next element
{
prev($ids); // move flag back because invoking 'next()' above moved the flag forward
$userA = current($ids); // store the current element
next($ids); // move flag to next element
$userB = current($ids); // store the current element
echo(' userA='.$userA['user_id']);
echo('; userB='.$userB['user_id']);
echo("<br/>");
}
}
You'll get this text on the screen:
userA=1; userB=2
userA=2; userB=3
userA=3; userB=4
userA=4; userB=5
userA=5; userB=6
userA=6; userB=7
userA=7; userB=8
You get the first item, then loop over the rest and at the end of each loop you move the current item as the next first item ... the code should explain it better:
if (false !== ($userA = current($ids))) {
while (false !== ($userB = next($ids))) {
// do stuff with $userA['user_id'] and $userB['user_id']
$userA = $userB;
}
}
Previous answer
You can chunk the arrays into pairs:
foreach (array_chunk($ids, 2) as $pair) {
$userA = $pair[0]['user_id']
$userB = $pair[1]['user_id']; // may not exist if $ids size is uneven
}
See also: array_chunk()

How do you remove an array element in a foreach loop?

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);

Categories