Add certain results in a foreach to a shared container element - php

I'm struggling to verbalise this question, but hopefully I can demonstrate it:
I wish for certain results in a foreach loop to be grouped together in a container in the front-end.
So, if, for example, I have a foreach loop running through an array of car names and colours:
foreach($cars as $car){
echo '<h1>'.$car->name.'</h1>';
echo '<p>'.$car->colour.'</p><br/>';
}
It may give me:
<h1>Car1</h1>
<p>Blue</p><br/>
<h1>Car2</h1>
<p>Blue</p><br/>
<h1>Car3</h1>
<p>Red</p><br/>
However I need to group results with the same colour into a container div, so the output looks like:
<div class="blue">
<h1>Car1</h1>
<p>Blue</p><br/>
<h1>Car2</h1>
<p>Blue</p><br/>
</div>
<h1>Car3</h1>
<p>Red</p><br/>
Because the container div is technically outside of each loop I'm not sure how I can get it in there without using front-end script (i.e. javascript), but I'm hoping there's a way… any ideas? Perhaps even a way to identify the first of a type and the last of a type - but that's the closest I can get to a theory, let a lone a solution.
Edit: It appears there was some misunderstanding over the question. I wasn't looking to programatically group within the foreach, simply 'wrap' pre-grouped items.

Use a multi-dimensional array to build your data structure, then loop through the array to display your output.
Something like this:
$mycars = array();
foreach($cars as $car){
$mycars[$car->colour][] = $car;
}
Now you have an array that looks like this:
Array
(
[Blue] => Array
(
[0] => {Car1Object}
[1] => {Car2Object}
)
[Red] => Array
(
[0] => {Car3Object}
)
)
Now loop through that array to display your output:
foreach($mycars as $colour => $cars) {
echo "<div class='$colour'>";
foreach($cars as $car) {
echo "<h1>{$car->name}</h1>";
echo "<p>{$car->colour}</p>";
}
echo "</div>";
}
And you get...
<div class='Blue'>
<h1>Car1</h1>
<p>Blue</p>
<h1>Car2</h1>
<p>Blue</p>
</div>
<div class='Red'>
<h1>Car3</h1>
<p>Red</p>
</div>

Related

Send associative array from a multiple select

I need to send an associative array from a multiple select.
I have this code:
<select name="frontend_footer_menu_pages[]" id="frontend_footer_menu_pages" class="form-control" multiple>
<?php foreach($pages as $page): ?>
<option value="<?php echo $page->url; ?>">
<?php echo $page->page; ?>
</option>
<?php endforeach; ?>
And this is producing:
Array(
[0] => first/page,
[1] => second/page
)
I need to obtain something like this:
Array(
['first/page'] => 'First Page',
['second/page'] => 'Second Page']
);
I am not able to produce name/value in associative way and not in numeric way because I can't retrieve the content of option ($page->page)
Thank you in advance
G
When the form is submitted you will indeed get something like this array in PHP:
Array(
[0] => first/page,
[1] => second/page
)
This is how it works, and I would not suggest to try to change this behaviour. However, you can convert this to the associative array of your liking.
First create an associative array for your pages, so you can quickly find the page name for a given url:
// Create hash for the pages, keyed by their page name:
foreach ($pages as $page) {
$pageHash[$page->page] = $page->url;
}
You already have your submitted list of selected items. Your existing code will have something like this:
$selected = $_POST['frontend_footer_menu_pages'];
Now, to convert this to the associative array you are looking for, just use array_intersect with the hash we created above, and then swap keys and values with array_flip:
$selected = array_flip(array_intersect($pageHash, $selected));
The outcome will be something like this:
Array
(
[first/page] => First Page
[second/page] => Second Page
)

Breaking a MultiDimensional Array into a Single Dimension

I have fields in mySQL which is currently being stored like this under the field "tags"
Shopping|Health & Beauty
Coffee|Shopping
What I'm trying to do is to loop through this to create a single dimension array and to grab only the unique values.
I have my query selecting DISTINCT tags from TABLE and run the loop like this:
while ($row_tags = mysql_fetch_assoc($r_tags)) {
$tags = $row_tags['tags'];
$imploded_tags[] = explode("|",$tags);
}
echo "<pre>";
print_r($imploded_tags);
The result from the print_r is showing it as a multidimensional array. I've tried to reexplode it and implode it in different ways, but I haven't been able to get any success. Is there a way that I can create this into a single dimension array? Not all tags will have an equal amount of tags separated by |, so I can't seem to get it to go with a function that I tried from another StackOverflow post. Any help would be greatly appreciated!
OUTPUT:
Array
(
[0] => Array
(
[0] => Shopping
[1] => Health & Beauty
)
[1] => Array
(
[0] => Coffee
[1] => Shopping
)
try this
while ($row_tags = mysql_fetch_assoc($r_tags)) {
$tags = $row_tags['tags'];
$tags = explode("|",$tags);
foreach($tags as $v){
$imploded_tags[] = $v;
}
}
I would do something like:
$imploded_tags = array_merge(explode("|",$tags), $imploded_tags);
}
$imploded_tags = array_unique($imploded_tags);
echo "<pre>";
print_r($imploded_tags);
See the manual on array_merge and array_unique.
However, I do think you are not using the right way to store your tags; they should be stored in a separate table as separate values.
What's going on is when you're fetching your rows from MySQL, you're essentially getting a bunch of data in an array in the first place, which is why you have to loop through them.
With your your implode function, you're taking a bunch of strings, then getting another array set and then appending that to an external array.
If you really wanted to get a single dimensional array without having this multidimensional thing going on, all you really need to do is utilize another loop within that loop.
$all_tags = array();
while ($row_tags = mysql_fetch_assoc($r_tags)) {
$tags = $row_tags['tags'];
$imploded_tags[] = explode("|",$tags);
for($i = 0; $i < count($imploded_tags); $i++) {
$all_tags[] = $imploded_tags[$i]
}
}
print_r($all_tags);

iterating through a changeable JSON array

I'm working on a web application that takes its data from a web page using the Yahoo Query Language API to return a JSON array. I've hit a block in that sometimes, when there is only one "race" on the page, the array is setup differently and I can't iterate through it in some circumstances. Let me explain in an example.
Array layout for a page with mutiple races
Array (
[div] => array (
[0] => array (
['venue_id'] = 02222
['venue_name'] = 'Hove'
['race_id'] = 9222
)
[1] => array (
['venue_id'] = 03333
['venue_name'] = 'Romford'
['race_id'] = 2442
)
//...and so on
)
)
Array layout for a page with just one race
Array (
[div] => array (
['venue_id'] = 02222
['venue_name'] = 'Hove'
['race_id'] = 9222
)
)
In the application, I'm currently using a simple foreach statement to iterate through the array. However, this obviously wont work with the second example and I need a workaround.
Example of foreach statement
foreach($result['div'] as $race) {
echo 'Venue ID: '.$race['venue_id'];
echo 'Venue Name: '.$race['venue_name'];
echo 'Race ID: '.$race['race_id'];
}
Any help would be massively appreciated!
Dan
I'd do this..
if(!isset($array['div'][0]))
$array['div'] = array($array['div']);
This way I do not have to have two iteration methods.
Take a look at the count value which is returned with all YQL result sets. If there is only one result, then force it to be an array (with one item) just like when there are multiple results.
So, something like…
if ($yql['query']['count'] == 1) {
$yql['results']['data'] = array($yql['results']['data']);
}
This way, the rest of your script doesn't need to care about the structure of the results.
What about:
if ( isset($result['div'][0])){
//first iteration method
} else{
//second iteration method
}
As simple as:
function format_race($race) {
echo 'Venue ID: '.$race['venue_id'];
echo 'Venue Name: '.$race['venue_name'];
echo 'Race ID: '.$race['race_id']
}
if (isset($result['div']['venue_id'])) {
format_race($result);
} else {
array_map('format_race', $result);
}
This also has the advantage of abstracting the data manipulation in an external function, which can come handy in many situations.
Please note that here I'm abusing a little of array_map, probably using foreach($result as $race) would make your program more readable for other php programmers if all you have to do is just printing.

How to search array for duplicates using a single array?

I am checking a list of 10 spots, each spot w/ 3 top users to see if a user is in an array before echoing and storing.
foreach($top_10['top_10'] as $top10) //loop each spot
{
$getuser = ltrim($top10['url'], " users/" ); //strip url
if ($usercount < 3) {
if ((array_search($getuser, $array) !== true)) {
echo $getuser;
$array[$c++] = $getuser;
}
else {
echo "duplicate <br /><br />";
}
}
}
The problem I am having is that for every loop, it creates a multi-dimensional array for some reason which only allows array_search to search the current array and not all combined. I am wanting to store everything in the same $array. This is what I see after a print_r($array)
Array ( [0] => 120728 [1] => 205247 ) Array ( [0] => 232123 [1] => 091928 )
There seems to be more to this code. As there are variables being called in it that aren't defined, such as $c, $usercount, etc.. And using array_search with the 2nd parameter of $array if it doesn't exist is not a good idea also. Since it seems like $array is being set within the if statement for this only.
And you don't seem to be using the $top10 value within the foreach loop at all..., why is this?
It would help to see more of the code for me to be able to help you.

foreach loop corrupting my array?

Explanation
I have a multidimensional array that is iterated over to created a categorized view of people with different research interests. The main array look something like this:
Array
(
...
['Cell Biology'] => Array(4 elements)
['Molecular'] => Array(6 elements)
['Biology Education'] => Array(14 elements)
['Plant Biology'] => Array(19 elements) <--- Last element in array
)
I know that the entire array is intact and correctly structured. The only information that is inside these array is an user id, like so:
Array ('Plant Biology') 19 elements
(
[0] => 737
[1] => 742
[2] => 748
...
)
My problem is that after i run the main array through a foreach loop the last 'sub-array' gets messed up. By messed up I mean that what you see about instead look like:
String (13 characters) 'Plant Biology'
This is without doing at all anything inside the loop with to the array that gets corrupted.
Any tips to what it might be?
PHP Code
// ---> Array is OK here
echo "<h2>Research divided</h2>";
// Loop areas and list them in 2 columns
foreach($research['areas'] as $area => $areaArray) {
// ---> Here it is already corrupted
$count = count($areaArray);
if($count > 0) {
echo "<h3>$area</h3><hr/>";
echo "<ul>";
// Loop users within areas, divided up in 2 columns
for($i=0 ; $i<$count ; $i++) {
$uid = $areaArray[$i];
echo "<li>$uid</li>";
}
echo "</ul>";
}
}
Are $area or $areaArray being used in different function elsewhere in your script? Wht happens if you rename them to $loop_area and $loop_areaArray to prevent accidental overwriting of variables?
It looks like an error that can occur if you loop over the array previously by referance using the same variable name for the value.
So if earlier in your code $areaArray is used in a foreach by referance it might corrupt your data.
Make sure both variables in your foreach are not used previously or unset them before the loop.
Check out:
http://bugs.php.net/29992
For more info on this kind of problem.

Categories