Multidimensional Array Pushing/Adding? - php

I want to create something like the following array
[Schedule_Date_Group] => Array
(
[Schedule_Date] => Array
(
[Friday, September 16, 2011] => Array
(
[Schedule_Item] => Array
(
[nid] => 763
[time] => 1:15 PM
[title] => What a Publisher Does: 5 Reasons Why You Need a...
[event_type] => events
[length] =>
[movie_type] =>
[details] =>
)
[Schedule_Item] => Array
(
[nid] => 763
[time] => 1:15 PM
[title] => What a Publisher Does: 5 Reasons Why You Need a...
[event_type] => events
[length] =>
[movie_type] =>
[details] =>
)
)
)
)
But I have a few issues, first the array seems to be getting created with a preceding # for the first value. Example
[7] => Array
(
[Schedule_Date_Group] => Array
(
And my arrays are not pushing it under the Date Array ([Friday, September 16, 2011] => Array) They are just being added to the end as a normal array. Example
[7] => Array
(
[Schedule_Date_Group] => Array
(
[Schedule_Date] => Array
(
[Friday, September 16, 2011] => Array
(
[Schedule_Item] => Array
(
[nid] => 763
[time] => 1:15 PM
[title] => What a Publisher Does: 5 Reasons Why You Need a...
[event_type] => events
[length] =>
[movie_type] =>
[details] =>
)
)
)
)
)
[8] => Array
(
[Schedule_Item] => Array
(
[nid] => 764
[time] => 1:30 PM
[title] => Navigating the Road to Licensing Music For Your...
[event_type] => events
[length] =>
[movie_type] =>
[details] =>
)
)
How can I fix these two issues. They are again, #'s preceding the Schedule_Date_Group array and the sub arrays being added to the end rather then nested under the date group array.
PHP For the main schedule item and date group part
$xml[] = array("Schedule_Date_Group" => array("Schedule_Date" => array($pretty_date => array("Schedule_Item" => array("nid" => $do['nid'], "time" => $pretty_time, "title" => $title, "event_type" => $do['field_event_type_value'], "length" => $do['field_length_value'], "movie_type" => $do['field_movie_type_value'], "details" => $schedule_details)))));
PHP for the sub menu items
$xml[] = array("Schedule_Item" => array("nid" => $do['nid'], "time" => $pretty_time, "title" => $title, "event_type" => $do['field_event_type_value'], "length" => $do['field_length_value'], "movie_type" => $do['field_movie_type_value'], "details" => $schedule_details));
It is being looped through so there is no way for me to just create a giant array. And if a new "Schedule Date" is set it will create a new [Schedule_Date_Group] => Array
(
[Schedule_Date] => Array
(
[Friday, September 16, 2011] => Array
(
and all the sub content should go under that new one.
So I would end up with
DATE
- Schedule_Item 1
- Schedule_Item 2
- Schedule_Item 3
- Schedule_Item 4
New Date
- Schedule Item 5
- Schedule Item 6
etc...
Any help?

Firstly, using a huge array to manually generate some XML like this is not the way to do it. Use something like XMLWriter or DOM instead, then you can build your document on the fly as you obtain your data. However, if you really want to, or are forced to do it like this, read on...
Secondly, what you are trying to do cannot be done. This is because you want use the same array key for multiple entries which won't work - you will just end up overwriting your previous entry.
Thirdly, your numeric keys are appearing because you are using $xml[] (array_push() behaves in the same way) and it will always add a numeric key because you have not told it what you want your text key to be.
Fourthly, your extra items are being added to the outer level of the array because that is what you have told PHP to do. $xml[] will always add a new key to the outer level of the $xml variable because you have not told PHP you are dealing with an inner array.
Your structure needs to be more like this:
$scheduleDateGroup = array (
'Friday, September 16, 2011' => array (
// These are your schedule items...
0 => array( ... ),
1 => array( ... ),
2 => array( ... ),
...
),
'Saturday, September 17, 2011' => array (
0 => array( ... ),
1 => array( ... ),
2 => array( ... ),
...
),
...
);
...and you can push new items onto specific days like this:
$scheduleDateGroup[$date][] = array( ... );
Then you can loop through it and turn it into XML with something like this:
echo "<Schedule_Date_Group>\n";
foreach ($scheduleDateGroup as $day => $schedules) {
echo " <Schedule_Date date=\"$day\">\n";
foreach ($schedules as $item) {
echo " <Schedule_Item";
foreach ($item as $attr => $value) echo " $attr=\"$value\"";
echo " />\n";
}
echo " </Schedule_Date>\n";
}
echo "</Schedule_Date_Group>";

Related

Moving values from one array to another in PHP

I have tried doing this for a while and can't wrap my head around it. I have two arrays. One array that contains sensors information called $sendatas and another that contains where those sensors are allocated to called $zones.
I want to be able to create dynamic HTML checkboxes within a table row based on whether the sensor is allocated to a zone or not and if it is then show a checked checkbox and if it isn't then show an unchecked checkbox.
Here is an example of my arrays:
The $sendatas array:
[1] => Array
(
[hwserial] => 00002025
[name] => FG05 Room Temp
[serial] => 5
[chan] => 1
[alarmhigh] => 30
[alarmlow] => 5
[delay] => 10
)
[2] => Array
(
[hwserial] => 00002025 01
[name] => FG05 Kitchen 1 Freezer
[serial] => 5
[chan] => 2
[alarmhigh] => -10
[alarmlow] => -35
[delay] => 10
)
The $zones array:
[0] => Array
(
[serial] => 1
[idGrid] => 50
[name] => All Sensors
)
[1] => Array
(
[serial] => 1
[idGrid] => 52
[name] => Food Area
)
[2] => Array
(
[serial] => 2
[idGrid] => 50
[name] => All Sensors
)
[3] => Array
(
[serial] => 2
[idGrid] => 52
[name] => Food Area
)
[4] => Array
(
[serial] => 3
[idGrid] => 50
[name] => All Sensors
)
[5] => Array
(
[serial] => 3
[idGrid] => 52
[name] => Food Area
)
[6] => Array
(
[serial] => 4
[idGrid] => 50
[name] => All Sensors
)
Both of my zones are not the same length. What I want to be able to achieve is to create an array that looks like this by finding the serial keys that match from both arrays.
Array
(
[0] => Array
(
[hwserial] => 00001216
[name] => Fridge Office Thermal
[serial] => 1
[chan] => 1
[alarmhigh] => 8
[alarmlow] => -2
[delay] => 10
[idGrid1] => 50
[idGrid2] => 51
[idGrid3] => 52
[zonename1] => All Sensors
[zonename2] => Office
[zonename3] => Food Area
)
[1] => Array
(
[hwserial] => 00002025
[name] => FG05 Room Temp
[serial] => 5
[chan] => 1
[alarmhigh] => 30
[alarmlow] => 5
[delay] => 10
[idGrid] => 50
[idGrid] => Not Used
[idGrid] => 52
[zonename1] => All Sensors
[zonename2] => Not Used
[zonename3] => Food Area
)
I am pretty sure I can write the code for the checkboxes once I have this array formatted properly. I have tried using some foreach loops but just keep making a mess of it. I have so far tried this on and off for a few weeks hoping it would just come to me but it hasn't. Any help appreciated.
Based on what you said you're trying to do with this, I think it looks like the array you're trying to create will not be that easy to work with. I think your sensors array is fine, and you just need to focus on the $zones array.
foreach ($zones as $zone) {
$zones_sensors[$zone['idGrid']]['name'] = $zone['name'];
$zones_sensors[$zone['idGrid']]['sensors'][$zone['serial']] = true;
}
This will reorganize the data in your $zones array into this format:
$zones_sensors = [
50 => ['name' => 'All Sensors', 'sensors' => [1 => true, 2 => true, 3 => true]],
51 => ['name' => 'Office', 'sensors' => [1 => true]],
52 => ['name' => 'Food Area', 'sensors' => [1 => true, 2 => true, 3 => true]]
];
This provides the two things you need to output the checkboxes as you described.
A complete list of zones
An indexed collection of serials associated with each zone.
You can use it to output headers for all the zones
foreach ($zones_sensors as $zone_id => $zone) {
// output one row with headers for zones
echo $zone['name']; // (formatting up to you)
}
Then when you output the sensors it will be easy to find which zones they're allocated to.
foreach ($sendatas as $sensor) { // make a row for each sensor
foreach ($zones_sensors as $zone_id => $zone) { // iterate the full list of zones
// check if the sensor is allocated to that zone
if (isset($zone['sensors'][$sensor['serial']])) {
// checkbox is checked
} else {
// checkbox is unchecked
}
}
}
This should just be a matter of creating a new array (let's call it $combined) that is a clone of one of the $sendatas array but uses the [serial] as a key so that you can target specific item. You would loop through the $zones array and for each item check if the [serial] is found in $combo and if a match is found inject the [idgrid] and [name] as a sub array for $combined['serial']. As you have not used sub array you could add a counter to add an incrementing number of values.
Something along the lines of this should do the trick:
$results = [];
foreach ($sendatas as $sensor) {
$zone_counter = 0;
foreach ($zones as $zone) {
if ($zone['serial'] == $sensor['serial']) {
$zone_counter++;
$sensor['idGrid' . $zone_counter] = $zone['idGrid'];
$sensor['zonename' . $zone_counter] = $zone['name'];
}
}
$results[] = $sensor;
// if you only want $results to contain sensors that actually have zones,
// wrap it in an if-statement:
// if ($zone_counter > 0) {
// $results[] = $sensor;
// }
}
print_r($results);
Note that this won't give you any sensors with matching zones with the data you provided, because those two sensors both have [serial] => 5 and all your zones have [serial] => 1 through 4. If you want to match by some other key instead of serial, just change the if-statement.

How to group these arrays accordingly?

I'm using PDO to run a mysql query with 2 joins and this is the result I get from the database:
Array
(
[0] => Array
(
[id] => 489
[cluster_id] =>
[label_value_id] => 4
[label_id] => 1
[int_value] => 40
)
[1] => Array
(
[id] => 489
[cluster_id] =>
[label_value_id] => 6
[label_id] => 2
[int_value] => 20
)
[2] => Array
(
[id] => 489
[cluster_id] =>
[label_value_id] => 9
[label_id] => 3
[int_value] => 10
)
)
The idea is that there will be multiple id's later on but for simplicities sake I only have 1 entry with id 489 for now.
I need the 3 arrays (cause of the joins) to be 1 array that looks something like this, I want a subarray based on the label-value_id => int_value relationship:
Array
(
[0] => Array
(
[id] => 489
[cluster_id] =>
[label_value_id] => 4
[label_id] => 1
[int_value] => 40
[vector_data] => Array
(
[4] => 40
[6] => 20
[9] => 10
)
)
)
I'd rather have this done in the PHP and not the Query because I dont have control over the queries when I implement this into the live application.
Any help is much appreciated!
You can use another container for gathering all batches which share the same id using its keys to transfer them. On initialization, create another container for that vector, then just push them line any normal array value:
$result = array();
foreach($array as $values) {
// initialization
if(!isset($result[$values['id']])) {
$result[$values['id']] = $values;
}
$result[$values['id']]['vector_data'][$values['label_value_id']] = $values['int_value'];
}
// $result = array_values($result); // optional key reindex
Sample Output
You can process your array from DB like this:
$pdo = array(
array(
"id" => 489,
"label_value_id" => 4,
"int_value" => 40,
),
array(
"id" => 489,
"label_value_id" => 6,
"int_value" => 20,
),
array(
"id" => 489,
"label_value_id" => 9,
"int_value" => 10,
),
);
$result = array();
foreach ($pdo as $array) {
if (!isset($result[$array['id']])) {
$result[$array['id']] = array(
"id" => $array['id'],
"vector_data" => array()
);
}
$result[$array['id']]['vector_data'][$array['label_value_id']] = $array['int_value'];
}
I have the same situation, and i solve it through PDO.
Here available examples. I reach same result with code:
$sth->fetchAll(PDO::FETCH_ASSOC|PDO::FETCH_GROUP);
think you should try it...

Complicated PHP transpose / pivot

I have the following array :
Array
(
[0] => Array
(
[Name] => first_data
[building] => A
[apt] => 16
)
[1] => Array
(
[Name] => first_data
[building] => B
[apt] => 16
)
[2] => Array
(
[Name] => second_data
[building] => A
[apt] => 17
)
[3] => Array
(
[Name] => second_data
[building] => B
[apt] => 18
)
and I need it to be returned as :
Array
(
[0] => Array
(
[Name] => first_data
[A] => 16
[B] => 16
)
[1] => Array
(
[Name] => second_data
[A] => 17
[B] => 18
)
Any ideas?
BTW the first array has hundreds of entries (not only first_data, but second and etc...) plus it has more than A and B.
Thanks in advance.
Not exactly what you want, but if you instead index the new array by the name, you can do this very easily. If the index number is some kind of ID, you can just create a field for it
foreach ( $oldarray as $index => $piece )
{
$newarray[$piece['Name']] = array($piece['building'] => $piece['apt'])
}
This will give you
Array
(
['first_data'] => Array
(
['A'] => 16,
['B'] => 16
)
['second_data'] => Array
(
['A'] => 17,
['B'] => 18
)
)
Since you have two entries with the same new, when you hit the 2nd loop, it will simply add the other building name. If you can work with this layout, then your solution is very easy, it will take more steps to do it exactly as you showed. If you absolutely have to do it the way you showed, you need extra code to loop through the new array, find the building name, add the key in the correct place, but this will be slower if you have a large amount of data.
In my opinion, the way I presented it is a far easier way to look around the array too. If you wanted to know the apt value for A in "second_data" you can just do
$newarray['second_data']['A']
with your array layout, it would require a loop to search the array for "second_data" because you have no idea where it is.

complex multidimentional associative array process with foreach

I've had to ask this one again, sorry, but I'm having a problem trying to process this array. I have tried several different ways but none where right, here's the array:
Array (
[search] => Array (
[response] => Array (
[errors] =>
[number_of_hotels] => 1 of 1
)
[lr_rates] => Array (
[hotel] => Array (
[hotel_ref] => 3116
[hotel_currency] => [U] => USD
[hotel_rooms] => Array (
[room] => Array (
[ref] => 6382
[type] => 1
[type_description] => Standard
[sleeps] => 8
[rooms_available] =>
[adults] => 8
[children] =>
[breakfast] => false
[dinner] => false
[description] =>
[alternate_description] =>
[rack_rate] => 82.01
[date] => 19/08/201220/08/201221/08/2012
[numeric_hotelcurrencyprice] => FullFullFull
[formatted_date] => 19 August 201220 August 201221 August 2012
[price] => FullFullFull
[hotelcurrencyprice] => FullFullFull
[numeric_price] => FullFullFull
[requested_currency] => GBPGBPGBP
[numeric_hotelcurrencyprice] => FullFullFull
[available_online] => false
[minimum_nights] => 1
[bed_type] =>
[cancellation_policy] =>
[cancellation_days] =>
[cancellation_hours] =>
[room_terms] =>
)
[room] => Array (
[ref] => 6382
[type] => 1
[type_description] => Standard
[sleeps] => 8
[rooms_available] =>
[adults] => 8
[children] =>
[breakfast] => false
[dinner] => false
[description] =>
[alternate_description] =>
[rack_rate] => 82.01
[date] => 19/08/201220/08/201221/08/2012
[numeric_hotelcurrencyprice] => FullFullFull
[formatted_date] => 19 August 201220 August 201221 August 2012
[price] => FullFullFull
[hotelcurrencyprice] => FullFullFull
[numeric_price] => FullFullFull
[requested_currency] => GBPGBPGBP
[numeric_hotelcurrencyprice] => FullFullFull
[available_online] => false
[minimum_nights] => 1
[bed_type] =>
[cancellation_policy] =>
[cancellation_days] =>
[cancellation_hours] =>
[room_terms] =>
)
)
[cancellation_type] => First Night Stay Chargeable
[cancellation_policy] => 2 Days Prior to Arrival
[CityTax] => Array (
[TypeName] =>
[Value] =>
[OptedIn] =>
[IsCityTaxArea] =>
)
)
)
)
)
Ok, I need to traverse the array and create a loop, so for every instance of ROOM it will repeat the process. Then i need to extract the data from room array and use it to populate rows in MySQL for each instance of room.
This is the code I have so far which prints the names and values in the room array. However, it only gets one of the room arrays. What can I do to read all of the rooms? I am also thinking this is too many for-each but don't seem to be able to traverse down ['']['']['']...
or by just using the associative name.
foreach($arr['search'] as $lr_rates) {
foreach($lr_rates['hotel'] as $hotel) {
foreach($hotel['room'] as $field => $value){
print $field;print $value;
}
}
}
It might also be worth mentioning the values in these arrays are always fluctuating.
I think you can really simplify this quote a bit. If you know that this will always be the structure then you can jump right down into the hotels and then into the rooms.
foreach($arr['search']['lr_rates']['hotel'] as $hotel) {
// You can access all of the keys in the hotel array here
foreach($hotel['hotel_rooms'] as $room) {
// Do stuff with the room array
}
}
I would recommend either building your insert script on the fly and calling the database just once for the write, or if you are updating then using a transaction. As the number of rooms gets larger you will slow your script down with a bunch of writes to disk.
the formatting of your data's output is very bad and unreadable. I cannot really identify what you are trying to do.
possibility: the inner array [hotel_rooms] => Array () uses the key room multiple times. as array keys are unique, you overwrite the data at the index room. this is why you only get one room.
possibility: there are rooms inside a room -> use a recursive function to iterate over all rooms like this:
function handleRoom(array $room) {
// do something with $room
if (array_key_exists('room', $room)) {
handleRoom($room['room']);
}
}
$room = array(
'some' => 'room',
'data' => 'and another',
'room' => array(
'is' => 'inside',
'of the' => 'main room',
),
);
handleRoom($room);

complicated multidimentional array process with foreach

im having a problem trying to process this array tried several different ways but none where right, here's the array
Array (
[search] => Array (
[response] => Array (
[errors] =>
[number_of_hotels] => 1 of 1
)
[lr_rates] => Array (
[hotel] => Array (
[hotel_ref] => 3116
[hotel_currency] => [U] => USD
[hotel_rooms] => Array (
[room] => Array (
[ref] => 6382
[type] => 1
[type_description] => Standard
[sleeps] => 8
[rooms_available] =>
[adults] => 8
[children] =>
[breakfast] => false
[dinner] => false
[description] =>
[alternate_description] =>
[rack_rate] => 82.01
[date] => 19/08/201220/08/201221/08/2012
[numeric_hotelcurrencyprice] => FullFullFull
[formatted_date] => 19 August 201220 August 201221 August 2012
[price] => FullFullFull
[hotelcurrencyprice] => FullFullFull
[numeric_price] => FullFullFull
[requested_currency] => GBPGBPGBP
[numeric_hotelcurrencyprice] => FullFullFull
[available_online] => false
[minimum_nights] => 1
[bed_type] =>
[cancellation_policy] =>
[cancellation_days] =>
[cancellation_hours] =>
[room_terms] =>
)
[room] => Array (
[ref] => 6382
[type] => 1
[type_description] => Standard
[sleeps] => 8
[rooms_available] =>
[adults] => 8
[children] =>
[breakfast] => false
[dinner] => false
[description] =>
[alternate_description] =>
[rack_rate] => 82.01
[date] => 19/08/201220/08/201221/08/2012
[numeric_hotelcurrencyprice] => FullFullFull
[formatted_date] => 19 August 201220 August 201221 August 2012
[price] => FullFullFull
[hotelcurrencyprice] => FullFullFull
[numeric_price] => FullFullFull
[requested_currency] => GBPGBPGBP
[numeric_hotelcurrencyprice] => FullFullFull
[available_online] => false
[minimum_nights] => 1
[bed_type] =>
[cancellation_policy] =>
[cancellation_days] =>
[cancellation_hours] =>
[room_terms] =>
)
)
[cancellation_type] => First Night Stay Chargeable
[cancellation_policy] => 2 Days Prior to Arrival
[CityTax] => Array (
[TypeName] =>
[Value] =>
[OptedIn] =>
[IsCityTaxArea] =>
)
)
)
)
)
ok i need to traverse the array and create a loop so for every instance of room it will repeat the process then i need to extract the data from room array and use it to populate rows in MySQL there will be multiple instances of room this is the code i have so far which prints the names and values in the room array but it only gets one of the room arrays what can i do to set it up to read them all and i am also thinking this is too many for-each but don't seem to be able to traverse down ['']['']['']...
or by just using the associative name.
foreach($arr['search'] as $lr_rates) {
foreach($lr_rates['hotel'] as $hotel) {
foreach($hotel['room'] as $field => $value){
print $field;print $value;
}
}
}
it mite also be worth mentioning the values in these arrays are always fluctuating
you don't have to use so much foreach loops in your script as it not looks good. this is an associative array.
you can simply access associate array by using its keys. do some google for it.you can find many scripts on this.
foreach($arr as $search) {
foreach($search as $lr_rates) {
foreach($lr_rates as $hotel) {
foreach($hotel as $hotel_rooms) {
print_r($hotel_rooms['room'])
}
}
}
}
EDIT: These many foreach loops are just to make understand how to reach to room. You can also get the result directly ofcourse.
print_r($arr['search']['lr_rates']['hotel']['hotel_rooms']['room']);

Categories