Can someone tell me what is wrong with this code :
foreach ($data as $region ):
foreach ($region as $type):
foreach ($type as $type2):
foreach ($type2 as $key=>$val):
if ($val=='background-color: FFFFFF;' || $val=='') unset($type2[$key]);
endforeach;
endforeach;
endforeach;
endforeach;
After print_r($data) seems that the data array is the same and unset is not working
Your loop is operating on copies of the original elements; changes to $type2 will not be visible in $data because $type2 is a copy.
You can solve this by iterating over all arrays by key, then indexing into $data with those keys to remove the value:
foreach ($data as $k1 => $region ):
foreach ($region as $k2 => $type):
foreach ($type as $k3 => $type2):
foreach ($type2 as $k4 =>$val):
if ($val=='background-color: FFFFFF;' || $val=='') {
unset($data[$k1][$k2][$k3][$k4]);
}
endforeach;
endforeach;
endforeach;
endforeach;
Of course this is ugly, but that's four nested loops will do. There is also the option if iterating by reference instead of grabbing keys, but personally I dislike that because of the nice opportunity to write bugs by reusing the abandoned references after the loop has ended. Especially in this case I dislike it to the fourth power.
use this, it should work:
foreach ($data as &$region ):
foreach ($region as &$type):
foreach ($type as &$type2):
foreach ($type2 as $key=>$val):
if ($val=='background-color: FFFFFF;' || $val=='') unset($type2[$key]);
endforeach;
endforeach;
endforeach;
endforeach;
the array values are passed as reference because of the & i put before the value variables. The unset will work this way
Related
I have a loop running in my project that I am not happy with and wondered if there is a more efficient way of achieving this?
I have an array like so
$myarray = ["value1", "value2", "value3"];
Then I want to go through another object ($sponsors) and only print out values on that has a field that matches the value in $myarray[]. Like so:
<?php foreach ($myarray as $value): ?>
<?php foreach ($sponsors as $post) : setup_postdata( $post );?>
<?php if($post['someValue'] == $value): ?>
//Do the work
<?php endif; ?>
<?php endforeach; ?>
<?php endforeach; ?>
This is working fine, but it might mean 50-60 loops just to grab and print out a few bits of markup. Is there a better way to do this?
EDIT NOTE: (based on initial replies) The order of the $myarray is important, this allows me to group the 'value1' together and then 'value2' etc
You can get rid of outer foreach loop
<?php foreach ($sponsors as $post) : setup_postdata( $post );?>
<?php if(in_array($post['someValue'], $myarray)): ?>
//Do the work
<?php endif; ?>
<?php endforeach; ?>
UPDATE
Given $sponsers is an array of posts, You can improve peformance by filterig posts based on some value by native array_filter() function So there are less posts for foreach to iterate over.
After this there is no need for if statement which will also improve performance.
<?php foreach ($myarray as $value): ?>
<?php $filteredPosts = array_filter($sponsors, function($post) use ($value) { return $post['someValue'] == $value; }); ?>
<?php foreach ($filteredPosts as $post) : setup_postdata( $post );?>
// do something
<?php endforeach; ?>
<?php endforeach; ?>
use in_array
ref in_array from here
<?php
foreach ($sponsors as $post) {
setup_postdata( $post );
if(in_array($post['someValue'],$myarray){
//Do the work
}
}
?>
Use in_array function
it takes three parameter but one is optional
for e.g. :
in_array($value, $myarray )
I have a problem with my foreach loop. My foreach loop basically looks like this:
echo $values[0];
echo $values[1];
foreach ($values as $key => $value)
{
echo $values[0];
echo $values[1];
}
$values[0] should be "new york city" and $values[1] should be "new york". The problem is that in the foreach loop, both echos give the same value, whereas outside the loop they give the different (correct) values.
How do I access the original array ($values) normally inside of the foreach loop?
EDIT: I don't want to access the value $value. I want to be able to access any index of $values regardless of which iteration my foreach loop is on. I hope I am making sense.
Also, obviously I have alot more going on in this foreach loop, it was just meant as an example. The purpose of the foreach loop is not to print out these values.
Basically what the actual foreach loop I am using does is that it iterate through an array, and when it finds a certain value in that array, it iterates through the whole array again (inside the foreach loop). So basically I want a foreach loop inside a foreach loop, both for the same array, but it doesn't seem to work.
Try to use $val instead of $values[$i];
// Code goes here
foreach ($values as $key => $value)
{
echo $value;
}
Basically I have a set of object values I want render in 2 separate html lists
I figure the simplest way to do this is by displaying evens only in one list, and odd only in the other
Here is the current code for displaying a single list
<ul>
<?php foreach ($values as $value) : ?>
<li><?php echo $value->value; ?></li>
<?php endforeach; ?>
</ul>
Try this:
<ul>
<?php
/* read the index key */
foreach ($values as $key => $value) :
/* skip the current element if it doesn't have an even index */
if($key % 2 == 1) continue;
?>
<li><?php echo $value->value; ?></li>
<?php endforeach; ?>
You didn't specify if the array has integer index. So I use a separate index pivot. This will do.
$v=array();
$index = 1;
foreach ($values as $value){
$v[($index++)%2][]=$value->value;
}
list ($evens, $odds) = $v;
echo "<ul><li>".implode("</li><li>", $odds)."</li></ul>"; // show list of odds
echo "<ul><li>".implode("</li><li>", $evens)."</li></ul>"; // shows list of even
This is what i am currently using
<?php $sidebar = $this->data['sidebar'];
$lastKey = array_pop(array_keys($sidebar));
$sidebar = $this->data['sidebar'][$lastKey]; ?>
<?php foreach($sidebar as $key => $item) { ?>
<li id="<?php echo Sanitizer::escapeId( "pt-$key" ) ?>"<?php
if ($item['active']) { ?> class="active"<?php } ?>><?php echo htmlspecialchars($item['text']) ?></li>
<?php } ?>
This is what i get (http://pastebin.com/t6Y2ZtMF) when i print_r($sidebar);
I want to get the last Array which is Categories and turn it into links.
I am new to php, so my method could be wrong even though it works. I is there a right way to pull the Categories Array or the above code is good as it is?
$lastValue = end($array);
$lastKey = key($array); // current key, which is the last since you called end()
After update:
You don't seem to be needing the key, only the array:
<?php $lastSidebarValue = end($this->data['sidebar']); ?>
<?php foreach ($lastSidebarValue as $key => $item) : ?>
business as usual...
<?php endforeach; ?>
Since you know you want the key 'Categories' though (not the last key), this seems the most logical thing to do:
<?php foreach ($this->data['sidebar']['Categories'] as $key => $item) : ?>
business as usual...
<?php endforeach; ?>
I think the end() function would be a great solution: http://php.net/manual/en/function.end.php
It basically returns the value of the last element in the array being passed to it.
$sidebar = end($sidebar);
If you want to get a key/value pair without popping & pushing the array, set the internal cursor to the end of the array and then use list and each to get the key & value.
// set up your array however you had it
$array = ...;
// move the cursor to the end of the array
end($array);
// use list() and each() to extract your key/value pair
list($key,$val) = each($array);
// $key will now have the last key
// $val will have the last value
perhaps, end:
$fruits = array('apple', 'banana', 'cranberry');
echo end($fruits); // cranberry
You can use `end()` instead of `array_pop()`. But both works for the **last element** of the array. The only difference is `end()` **points out** the **last element** of the array without effecting it and `array_pop()` **pops** the element off the **end** of array.
Please go through the following links for detail information
end() | array_pop()
I am working with SimplePie and I cannot figure out how to output the count, or the key values for the loop.
Shouldn't this
<?php foreach ($feed->get_items() as $item): ?>
<?php
$i = key($item);
echo $i;
?>
<?php endforeach; ?>
, or this
<?php foreach ($feed->get_items() as $item): ?>
<?php
$i = count($item);
echo $i;
?>
<?php endforeach; ?>
be outputting a unique number for each?
uniqid() Doesn't work in this case, because I am running the loop twice on the page and trying to match up one list of elements with another based on ID.
A single argument used with as is interpreted as a variable in which to store the value, not the key. If you want the key, you need to use => in a manner like the following:
foreach ($feed->get_items() as $key => $item):
echo $key;
endforeach
As a sidenote, you're using key() and count() on an item in the array, rather than the array as a whole, which is invalid. As far as I'm aware, there's no guarantee that key() will work as you expect even if applied to the whole array. It's meant for loops where you control the iteration, as with next.
To get the 'count' in a foreach you would need an extra variable. Getting the key is easy and the same if the array is indexed in order instead of associative. Here is an example including both:
$array = array(
'foo' => 'bar'
);
$i = 0;
foreach ($array as $key => $value)
{
/*
code where $i is the 'count' (index) and $key is the associative $key.
*/
/* $i == 0 */
/* $key == 'foo' */
/* $value == 'bar' */
$i++;
}
key($item) that you're using above doesn't work because you're trying to get the key of a value that no longer is associated with the original array.
count($item) is the count of a subarray $item.
you can use get_id() method
like :
foreach ($feed->get_items() as $item)
{
$prev_ids = array('guid1', 'guid2', 'guid3', 'guid4');
if (in_array($item->get_id(true), $prev_ids))
{
echo "This item is already stored.";
}
else
{
echo "This is a new item!";
}
}