PHP nested foreach is only taking first key - php

I am getting a lot of data from a form through POST. As an example, here is some of the data:
event_date:
Array (
[0] => 2017-04-02
[1] => 2017-04-02
[2] => 2017-04-03 )
equipment_name:
Array
(
[0] => Array
(
[0] => Mic
[1] => Sound System
[2] => Wireless Mic
[3] => Two Point Stage Wash
)
[1] => Array
(
[0] => Sound System
)
[2] => Array
(
[0] => Projection Package
[1] => Gobo
[2] => Audio Engineer
)
)
To save this data I am doing two foreach loops:
foreach ($_POST['event_date'] as $key => $date) {
echo "event number [".$key."]<br>";
//insert into table value $_POST['event_date'][$key]
foreach ($_POST['equipment_name'] as $ekey => $value) {
echo "equipment number [".$key."][".$ekey."]<br>";
//insert into table value $_POST['equipment_name'][$key][$ekey];
}
}
Unfortunately my result is the following:
event number [0]
equipment number [0][0]
equipment number [0][1]
equipment number [0][2]
event number [1]
equipment number [1][0]
equipment number [1][1]
equipment number [1][2]
event number [2]
equipment number [2][0]
equipment number [2][1]
equipment number [2][2]
As you can notice, the nested key ($ekey) equals the first key, not showing items over that number (eg: equipment number [0][3]), and saving nothing if the amount of equipment is lower than that number (eg: equipment number [1][1] and [1][2]).
Why the nested loop has this behavior? How could I solve this issue?

If I understood your question right, I think you want to access a particular nested array from $_POST['equipment_name'], yet you always access the outer array. This is a simple fix, change your second foreach to:
foreach ($_POST['equipment_name'][$key] as $ekey => $value) {
^^^^^^

Related

Moving array element to beginning of array?

If I have an array like the one below how would I go about moving key [2] and its associated value to the beginning of the array ? (making it key [0] and increasing the other keys by 1)
Current:
[0] => Array
(
[name] => Vanilla Coke cans 355ml x 24
)
[1] => Array
(
[name] => Big Red Soda x 24
)
[2] => Array
(
[name] => Reeses White PB Cups - 24 CT
)
Desired outcome:
[0] => Array
(
[name] => Reeses White PB Cups - 24 CT
)
[1] => Array
(
[name] => Vanilla Coke cans 355ml x 24
)
[2] => Array
(
[name] => Big Red Soda x 24
)
EDIT
To clarify I do will always want to move an element to the begining of the array but it wont necessarily be the last element it can sometimes be the 3rd 4th e.c.t. it varies each time.
array_splice removes (and optionally replaces / inserts) values from an array returning an array with the removed items. In conjunction with the simple array_unshift function the job could be done.
$arr = [1,2,3,4,5];
function array_move_item_as_first(array $array, int $idx) : array
{
array_unshift( $array, array_splice($array, $idx, 1)[0] );
return $array;
}
print_r(array_move_item_as_first($arr, 2));
output:
Array
(
[0] => 3
[1] => 1
[2] => 2
[3] => 4
[4] => 5
)
Why don't you use array_unshift and array_pop together?
array_unshift($someArray, array_pop($someArray));
array_pop removes the last element, and array_shift prepends the entry to the array.

How to merge sub-arrays based on first value php

I have an array that is put together. It's basically 24 data points across 7 stations. Each station has a data point each hour and a new sub0array is created for each data point. The problem with this, is I now want to split the data up based on station so I can sort it. When I go to do that array_filter doesn't work for me. I wanted to basically combine all of the values that have the same row 0 result in each sub-array. but keep each data point based on them. Row 0 is the station name. Here is an example of what the array looks like. There are 160 sub arrays. All I need to do is combine them together based on Station name. I was going to do this based on Array value, but the problem is if a data-point is missing, it breaks that logic.
Array
(
[0] => Array
(
[0] => STATIONONE
[1] => 02/22/15 04:00:00 PM
[2] => SW
[3] => Array
(
[0] => 4.51
)
[4] => MPH
[5] => Array
(
[0] => 16.1
)
[6] => MPH
)
[1] => Array
(
[0] => STATIONONE
[1] => 02/22/15 05:00:00 PM
[2] => S
[3] => Array
(
[0] => 2.7
)
[4] => MPH
[5] => Array
(
[0] => 9.61
)
[6] => MPH
)
And it just keeps repeating till I have 23 Values. Then the next station.
So 0-22 subarray value = station 1
23-45 subarray value = station 2
etc.. just stating to help show what I am trying to do.
It isn't entirely clear what you expect your output to be, but this might get you there:
$entriesByStation = []
foreach ($entries as $entry) {
$entriesByStation[$entry[0]] = $entry;
}
This will group all the the entries by station name in the $entriesByStation array
The accepted answer got me close into figuring this out. I had to do this by station though. So I just created 7 foreach statements and created an array for each station. This way I can also merge the array together if needed.
# Parse our All Data and set station
foreach ($array as $entry) {
if ($entry[0] === "STATIONONE"){
$S1pkwsite = ($entry[0]);
$S1pkwvalue = ($entry[5][0]);
$S1pkwdate = ($entry[1]);
$S1pkwunit = ($entry[6]);
$S1wspvalue = ($entry[3][0]);
$S1wspunit = ($entry[4]);
$S1wdrvalue = ($entry[2]);
$S1pkwdataarray[] = array('SiteName'=>$S1pkwsite,'DATE'=>$S1pkwdate,'WDR'=>$S1wdrvalue,'VALUE'=>$S1pkwvalue,'UNIT'=>$S1pkwunit);
}
}
array_push ($Stationone_data, $pkwdataarray);
$Stationone_data = array_shift($Stationone_data);

php array sorting and grouping

I have an array of Towns that have no sorting whatsoever. I would like to sort by the [category][3] which is the province and then the [category][0] which is the region and display each Grouped Province with its regions and then towns underneath it. So the following array:
Array
(
[0] => Array
(
[name] => Name One
[id] => 1
[link] => http://mylink1.com
[category] => Array
(
[0] => Region 1
[1] => Town 7
[2] => Country
[3] => Province 2
)
)
[1] => Array
(
[name] => Name Two
[id] => 2
[link] => http://mylink2.com
[category] => Array
(
[0] => Region 1
[1] => Town
[2] => Country
[3] => Province 3
)
)
[2] => Array
(
[[name] => Name Three
[id] => 3
[link] => http://mylink3.com
[category] => Array
(
[0] => Region 1
[1] => Town 5
[2] => Country
[3] => Province 2
)
)
[6] => Array
(
[name] => Name Four
[id] => 4
[link] => http://mylink4.com
[category] => Array
(
[0] => Region 1
[1] => Town 1
[2] => Country
[3] => Province 1
)
)
)
... should end up looking like this:
Country (all the same)
Province 1
- Region 1
- - Town 1 name, id, link
Province 2
- Region 1
- - Town 5 name, id, link
- - Town 7 name, id, link
Province 3
- Region 1
- - Town 1 name, id, link
Province is the Primary Grouping factor, then sorted by Region, the Towns in no particular order but I guess Alphabetically would make sense.
I have managed to sort the array by Category using this reference: Sort Multi-dimensional Array by Value but cannot fathom how to sort any further without referencing the Province specifically in a loop by using its name. i.e.
/// shortened version..
foreach($array as $key=>$value)...
if($value == "Province 1") : do something here with these matches
... etc
Any help would be appreciated.
Take a look at the uasort() function:
http://www.php.net/manual/en/function.uasort.php
I don't think that you can do this in one step.
You can group your values like this:
$grouped = array();
foreach ($data as $group)
{
$grouped[ $group['category'][3] ][ $group['category'][0] ][ $group['category'][1] ] = array(/* ... */);
}
But you will still have to sort every array (and it's sub-arrays) using ksort().
You should check, whether you can get the values already presorted. If you, for example, are using a database to retrieve this values, it would be quite trivial to sort them in the database and bring them in the correct (grouped) structure in your PHP code.
looping through the array I've used a switch for the category I'm looking for and then built another array for each group. from there I can sort by region:
foreach($arr as $town){
switch($town['blogcats']){
case "Province 1" : $province1[] = $town;
break;
case...
etc
}
}
Then each new grouped array can be output:
foreach($province1 as $eachtown) {
echo $newtown['name'];
... and so forth.
}
Within the second loop sorting could be done on the Region.
Each Province is manually referenced in a list on my page which also gives me control over placement.
Howver, this answer could also be improved... but the above works without too much effort.

Add Data to 3 Dim Array

I have the following array containing a master record of training courses held on a system (select_group just identifies related course groups):
Array
(
[DE00041-1] => Array
(
[select_group] => 1
)
)
The training course ids are then queried against a table containing only running courses whilst also grabbing extra information.
As one training course may run more than once per year they have a running_id which gives the following:
Array
(
[DE00041-1] => Array
(
[title] => xxx
[405] => Array
(
[start_quarter] => 1
[end_quarter] => 1
)
)
)
What I then need to do is add the original array select_group data into the newly created array.
The end result should be:
Array
(
[DE00041-1] => Array
(
[title] => xxx
[select_group] => 1
[405] => Array
(
[start_quarter] => 1
[end_quarter] => 1
)
)
)
I have looked over other SO / Google answers but couldn't find what I was looking for.
There may be 1-20 training courses listed, each one running once to four times per year.
foreach($yourArray as $key => $value){
$yourArray[$key]['select_group'] = $select_group_array[$key]['select_group'];
}
Another variant:
$result = array_merge_recursive($arr1, $arr2);

Combining Multidimensional Array Values in PHP

I have a multidimensional array which looks like this:
Array
(
[0] => Array
(
[0] => Array
(
[description] => UPS Ground
[delivery-time] => 1-5 business days
[shipping-amount] => 1299
)
[1] => Array
(
[description] => UPS 3 Day Select
[delivery-time] => 3 business days
[shipping-amount] => 2459
)
[2] => Array
(
[description] => UPS 2nd Day Air
[delivery-time] => 2 business days
[shipping-amount] => 3239
)
)
[1] => Array
(
[0] => Array
(
[description] => UPS Ground
[delivery-time] => 1-5 business days
[shipping-amount] => 864
)
[1] => Array
(
[description] => UPS 3 Day Select
[delivery-time] => 3 business days
[shipping-amount] => 1109
)
[2] => Array
(
[description] => UPS 2nd Day Air
[delivery-time] => 2 business days
[shipping-amount] => 1633
)
[3] => Array
(
[description] => UPS Overnight
[delivery-time] => 1 business day
[shipping-amount] => 3528
)
)
)
I'm trying to achieve 3 things:
Add the values of the shipping-amount where the description is the same across dimensions
Drop the array if it contains a description which doesn't exist in every other dimension
Drop a dimension once the shipping-amounts are combined
There may be several first-level arrays (not just 2 as shown here), but this is as deep as the dimensions will go. I'm looking for the following result:
Array
(
[0] => Array
(
[description] => UPS Ground
[delivery-time] => 1-5 business days
[shipping-amount] => 2163
)
[1] => Array
(
[description] => UPS 3 Day Select
[delivery-time] => 3 business days
[shipping-amount] => 3568
)
[2] => Array
(
[description] => UPS 2nd Day Air
[delivery-time] => 2 business days
[shipping-amount] => 4872
)
)
Thanks in advance!
I think this would work:
$final=array(); // the final array
$count=array(); // keeps track of instances of each description
$loops=count($array);
for($a=0;$a<$loops;$a++){
foreach($array[$a] as $s){ //loop through child arrays
if($count[$s['description']]>0){ //check if description exists in $count
foreach($final as $k=>$v){ //add sums to the final if it does exist
if($final[$k]['description']==$s['description']){$final[$k]['shipping-amount']+=$s['shipping-amount'];}
}
}else{ //if it doesn't exist in the count array, add it to the final array
$final[]=$s;
}
$count[$s['description']]++;//update the count array
}
}
//Unset singletons, using the count array
foreach($count as $k=>$v){
if($v==1){
foreach($final as $key=>$val){
if($final[$key]['description']==$k){unset($final[$key]);}
}
}
}
print_r($final);
I have been stuck on an issue for the past 2 days and feel you, so I hope this helps.
I'm not going to write code because I agree with deceze.
Nonetheless, my recommendation would be a custom function that:
loops over an input array
applies the logic you outlined
return the condensed array
Given your specific requirements isn't a single, magical PHP function that does this. Yet, there are dozens of PHP array functions you could utilize within your custom function.
If you need help on a particular piece, update your post or ask a new question.
I would recommend using the array_walk function with a callback that handles your specific requirements for addition and uniqueness.

Categories