foreach ($bing_array as $bing_array_val)
{
foreach ($final_array as $final_array_val)
{
if ($final_array_val["link"] == $bing_array_val["link"])
{
$final_array_val["rank"] += $bing_array_val["rank"];
}
}
}
The above code has two foreach loops, which are nested.
It should test every bing_array["link"] against every final_array["link"] and if they are the same, the final_array["rank"] value should be += bing_array["rank"] but when I echo final_array, the ["rank"] values are unchanged.
I assume this is a syntax problem, where am I going wrong?
Thanks
You need to use the reference syntax (& prefix):
foreach ($final_array as &$final_array_val)
{
}
unset($final_array_val);
Note that the unset is required to break the reference to the last value. Read more here.
Here is the actual code you need :
foreach ($bing_array as &$bing_array_val)
{
foreach ($final_array as &$final_array_val)
{
if ($final_array_val["link"] == $bing_array_val["link"])
{
$final_array_val["rank"] += $bing_array_val["rank"];
}
}
unset(&$final_array_val);
}
unset(&$bing_array_val);
In your initial code, each time you were looping on $final_array, it was creating a temporary value called $final_array_val containing the content. Then, you modified it, and then it was replaced for each occurence of the foreach.
By passing the variables by reference, instead of creating a new temporary variable in the foreach, you use the actual variable which will keep the modifications you have done to it.
Related
I made a post regarding a code for Adobe Analytics API. I am using a code to retrieve the first and second element (dimension) which is called 'breakdown'. The number varies depending on the data we have for this element.
I am using a loop with i=10 but I want to take everything. Which is the best way to achieve that?
I am using this code:
foreach ($json->report->data as $element)
{
// putting an excessive number for i
for ($i=0;$i<100;$i++)
{
// checking if the object exists
if (isset($element->breakdown[0]->breakdown[$i]->name))
{
echo $element->breakdown[0]->breakdown[$i]->name;
// putting the data in a list I created before
array_push($list, array(''.$element->year.'-'.$element->month.'-'.$element->day, $element->breakdown[0]->name, $element->breakdown[0]->breakdown[$i]->name, $element->breakdown[0]->breakdown[$i]->counts[0], $element->breakdown[0]->breakdown[$i]->counts[1]));
}
else
{
// Break the loop. All the objects are in the row. So, if there is not any for i=45 then there won't be any for i>45
continue;
}
}
}
where I am trying to get all the objects. I am checking if the objects exist. If they don't, I want this loop to stop (second loop).
Use break instead of continue to exit a loop
break stops the current loop continue goes to the next iteration of the loop.
To get out of both loops use break 2;
You can break the loop with break.
for more information: http://php.net/manual/en/control-structures.break.php
foreach ($json->report->data as $element)
{
// putting an excessive number for i
for ($i=0;$i<100;$i++)
{
// checking if the object exists
if (isset($element->breakdown[0]->breakdown[$i]->name))
{
echo $element->breakdown[0]->breakdown[$i]->name;
// putting the data in a list I created before
array_push($list, array(''.$element->year.'-'.$element->month.'-'.$element->day, $element->breakdown[0]->name, $element->breakdown[0]->breakdown[$i]->name, $element->breakdown[0]->breakdown[$i]->counts[0], $element->breakdown[0]->breakdown[$i]->counts[1]));
}
else
{
// Break the loop.
break;
}
}
}
New to php
I want to remove index with value from php session array. I'm using this code
$max=count($_SESSION['Item']);
for($i=0;$i<$max;$i++){
if(strpos($_SESSION['Item'][$i]['Name'],'Shipping')!== false)
{
unset($_SESSION['Item'][$i]);
break;
}
its working fine if value exists in last index of array. But if it exists in between. it doesn't work at all. Where am i going wrong?
Try to use array_splice, to remove items
array_splice($_SESSION['Item'], $i, 1);
I recommend using the foreach instead of for. This way your array keys can be more then only int. And is guaranteed to loop over all the array items
foreach($_SESSION['Item'] as $key => $value) {
if (strpos($value['Name'],'Shipping')!== false) {
unset($_SESSION['Item'][$key]);
}
}
As pointed out the break will stop the loop. So if you only want to remove a single entry, you should add the break
if(strpos($_SESSION['Item'][$i]['Name'],'Shipping')!== false)
{
unset($_SESSION['Item'][$i]);
}
Im trying to NOT show a specific field inside the loop, so I need to get a list of all the field types so I can use it inside the if statement. Not sure how I can do this properly?
foreach($this->sections as $k => $section){
foreach($section['fields'] as $k => $type){
//This makes a nice list of all the stuff I need
echo '<li>'.var_dump ($type['type']).'</li>';
}
//Outside the loop doesn't dump all of the contents just some
echo '<li>'.var_dump ($type['type']).'</li>';
if($type['type'] != 'switch'){
//My stuff
}
}
The idea is to loop all the field types, except for one specific type declared in the if statement. The for each is so I can get a list of all the field types.
As you might already experienced the construct you propose is not desired since the if statement will be executed after the loop has already ended.
You can use the continue keyword to jump to the next iteration and skip fields you're not interested in.
foreach ($section['fields'] as $k => $type) {
if ($type['type'] != 'switch') {
continue;
}
// do stuff
}
http://php.net/manual/en/control-structures.continue.php
I have nested arrays and want to append the content of one array into another when the keys match. Here is my function but instead of appending it is replacing.
function MergeArrays($arr, $ins)
{
if(is_array($arr))
{
if(is_array($ins))
foreach($ins as $k=>$v)
{
if(isset($arr[$k])&&is_array($v)&&is_array($arr[$k]))
{
$arr[$k] = MergeArrays($arr[$k], $v);
}
else
{
// This is the new loop :)
// while (isset($arr[$k]))
// $k++;
// HERE IS WHERE I WANT TO APPEND INSTEAD OF ADD
$arr[$k] = $v;
}
}
}
else if(!is_array($arr)&&(strlen($arr)==0||$arr==0))
{
$arr=$ins;
}
return($arr);
}
Any recommendations?
Thanks
You can merge the entries by either adding the arrays together, or using array_merge to merge the arrays into a new one.
Any reason you're not using array_merge_recursive to solve this without custom code?
I'm not sure I'm reading the question properly, I'm a little confused as to what you're doing, but this might help:
As far as I can tell, you want to append to the value of $arr[k] with the value of $v. Therefore you want to concat these things together.
Therefore you want to use .= instead of = on the line below your comment.
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);