PHP Multidimensional Array: Combine By Key And Add Values Of Another Key - php

have an array like this:
array (
'#attributes' =>
array (
'status' => 'ok',
),
'time_entries' =>
array (
'#attributes' =>
array (
'page' => '1',
'per_page' => '100',
'pages' => '1',
'total' => '33',
),
'time_entry' =>
array (
0 =>
array (
'time_entry_id' => '1411884',
'staff_id' => '22384',
'project_id' => '11116',
'task_id' => '3296',
'hours' => '1.75',
'date' => '2017-02-20',
'notes' => 'What is Quadra, Events Slider, Event Page Setup',
'billed' => '0',
),
1 =>
array (
'time_entry_id' => '1411254',
'staff_id' => '22384',
'project_id' => '11116',
'task_id' => '3296',
'hours' => '1.5',
'date' => '2017-02-17',
'notes' => 'Events Slider, Background overlay, Intro',
'billed' => '0',
),
2 =>
array (
'time_entry_id' => '1410694',
'staff_id' => '22384',
'project_id' => '11116',
'task_id' => '3296',
'hours' => '2.75',
'date' => '2017-02-16',
'notes' => 'Background Image SVGs, Header, Footer',
'billed' => '0',
),
3 =>
array (
'time_entry_id' => '1410586',
'staff_id' => '22384',
'project_id' => '11116',
'task_id' => '3296',
'hours' => '0.5',
'date' => '2017-02-15',
'notes' => 'Site Background
Assign Less Variables',
'billed' => '0',
),
4 =>
array (
'time_entry_id' => '1409621',
'staff_id' => '22384',
'project_id' => '11116',
'task_id' => '3296',
'hours' => '0.25',
'date' => '2017-02-14',
'notes' => 'Theme Install',
'billed' => '0',
),
...it actually goes on further than those first 4. What I am looking to do is sort these arrays by the key ["task_id"] so that I can group those together, and then add together the ["hours"] key - so that at the end I can output the total number of hours worked on under each task_id.
I've tried a bit of 'array_merge_recursive'and similar but I'm at a loss; this is PHP a good bit above my level. Help very appreciated.

So you're probably just better off doing a group by and summation by generating a new set of data rather than trying to modify this array.
Something like this will give you what you're looking for:
$time_entries = $your_array["time_entries"]["time_entry"];
$task_hours = [];
foreach ($time_entries as $time_entry) {
if (!isset($task_hours[$time_entry["task_id"]])) {
$task_hours[$time_entry["task_id"]] = 0;
}
$task_hours[$time_entry["task_id"]] += (float) $time_entry["hours"];
}
$task_hours would give you a value like:
Array
(
[3296] => 5
[1879] => 0.25
)

Instead of sorting the array and then summing the hours why not process over the relevant part of that array and do the summation all in one go.
$tots = array();
foreach( $array['time_entry'] as $task ) {
if ( isset($tots['task_id']) ) {
$tots['task_id'] += $task['hours'];
} else {
$tots['task_id'] = $task['hours'];
}
}
You should now have an array where the key is the task_id and its value is the summation of all that keys hours.
If you want the task_id's in order then sort the $tots array before outputing any results
ksort($tots);
If you want the results in order of the number of hours
asort($tots);

Related

compare an ID in array of arrays and take only a single row with the date in desc order in PHP

I have an array like this :
$data = array (
0 =>
array (
'UserID' => '1',
'ShipPinCode' => '411008',
'createdDate' => '2011-10-04 01:16:54.723',
'Amount' => '1000.00',
),
1 =>
array (
'UserID' => '1',
'ShipPinCode' => '411008',
'createdDate' => '2011-10-04 01:24:24.243',
'Amount' => '1000.00',
),
2 =>
array (
'UserID' => '102818',
'ShipPinCode' => '500072',
'createdDate' => '2011-11-29 12:17:43.880',
'Amount' => '2000.00',
),
3 =>
array (
'UserID' => '100001',
'ShipPinCode' => '500072',
'createdDate' => '2011-11-26 11:49:17.760',
'Amount' => '2000.00',
),
);
I want to sort it in such a way that for duplicate entries of UserID the final output should contain only a single row for that UserID where the createdDate is the largest i.e in descending order.
Desired output :
array (
0 =>
array (
'UserID' => '1',
'ShipPinCode' => '411008',
'createdDate' => '2011-10-04 01:24:24.243', //only took one row of UserID 1 where the createdDate is the largest.
'Amount' => '1000.00',
),
1 =>
array (
'UserID' => '102818',
'ShipPinCode' => '500072',
'createdDate' => '2011-11-29 12:17:43.880',
'Amount' => '2000.00',
),
2 =>
array (
'UserID' => '100001',
'ShipPinCode' => '500072',
'createdDate' => '2011-11-26 11:49:17.760',
'Amount' => '2000.00',
),
);
I'm not able to figure out how to do the comparison in such a case.
How do I do it?
You can sort ascending by the createdDate:
array_multisort(array_column($data, 'createdDate'), SORT_ASC, $data);
Then you can extract and index on UserID which will only keep the last one:
$result = array_column($data, null, 'UserID');
If you want to reindex (not needed):
$result = array_values($result);

Mongodb Search from Collection

I need to Search collection in mongodb having
'food_name' => 'fish'
and
'room_features' =>
array (
0 => 'Shower',
1 => 'Hairdryer',
),
I tried the following code. But the result is not-correct. I think multiple $eq is not allowed (same index in array).
array (
'$and' =>
array (
array (
'food' =>
array (
'$elemMatch' =>
array (
'food_name' =>
array (
'$eq' => 'fish',
),
),
),
),
array (
'room' =>
array (
'$elemMatch' =>
array (
'room_features' =>
array (
'$elemMatch' =>
array (
'$eq' => 'Shower'
'$eq' => 'Hairdryer'
),
),
'roomrate' =>
array (
'$eq' => new MongoInt32(2500),
),
),
),
),
),
)
Here is the document I need to search.
array (
'_id' => new MongoId("59670aca7fafd8342e3c9869"),
'subcat_name' => 'Test',
'place' => '',
'description' => '',
'created_date' => '1499970060',
'created_by' => 'Admin',
'openingtime' => '',
'closingtime' => '',
'hotel_class_id' => '594245f67fafd87e243c986a',
'hotel_type_id' => '594244177fafd884563c9869',
'latitude' => '0',
'longitude' => '0',
'dist_id' => '5911966a7fafd8c83c3c986a',
'cat_id' => '58fb230e7fafd883183c986d',
'featured' => '0',
'visited' => new MongoInt64(5),
'subcat_slug' => 'test-trivandrum-1',
'image' => NULL,
'food' =>
array (
0 =>
array (
'food_id' => '149992634012642164',
'region_id' => '5944ba947fafd883333c9869',
'food_name' => 'fish',
'type' => 'veg',
'rate' => '100',
),
1 =>
array (
'food_id' => '14999366891994980639',
'region_id' => '595c75c17fafd835173c986c',
'food_name' => 'curry',
'type' => 'veg',
'rate' => '1000',
),
),
'room' =>
array (
0 =>
array (
'room_id' => '14999346791721342880',
'roomtype' => 'DELUXE KING ROOM1',
'roomrate' => new MongoInt64(2500),
'image' => 'beach_icon33.png',
'room_features' =>
array (
0 => 'Shower',
1 => 'Hairdryer',
),
),
1 =>
array (
'room_id' => '14999346901389554873',
'roomtype' => 'DELUXE KING ROOM new',
'roomrate' => new MongoInt64(4000),
'image' => 'beach_icon34.png',
'room_features' =>
array (
0 => 'Shower',
1 => 'Bathrobe',
),
),
),
)
Please Give me an alternate way to search multiple item from array.
Thanks in advance.
I think if you want to query list you can add the list in query,
try this
{
"food" : {
"$elemMatch": {
"food_name" : "fish"
}
},
"room" : {
"$elemMatch": {
"room_features" : ["Shower", "Hairdryer"]
}
},
}
Hope this help.

Shopify orders array issue

I have these two arrays
$order2 = array('line_items' => array(
array('title' => 'Shipping',
'price' => '10',
'quantity' => '2',
)
));
$order3 =array('title' => 'Handling',
'price' => '5',
'quantity' => '1',
);
I've used array_merge and array_push in this instance but both don't give me my desired output. I'm trying to get it to show like this.
array('line_items' => array(
array('title' => 'Shipping',
'price' => '10',
'quantity' => '2',
),
array('title' => 'Handling',
'price' => '5',
'quantity' => '1',
)
));
The output i get is
Array ( [line_items] => Array ( [0] => Array ( [title] => Shipping [price] => 10 [quantity] => 2 ) ) [title] => Handling [price] => 5 [quantity] => 1 )
How can i achieve my desired output so i can use this as a shopify order?
You don't need any functions to do that, just a simple array assignment on top of the existing one:
$order2['line_items'][] = $order3;

Problems with merging arrays

I have a number of arrays like the one below. These are the result of data retrieved from the database. I need the final array to have the structure mentioned because I need to foreach loop each 'notes' in the successive code. I can't use a for loop only.
array('title' => 'Testing',
'content' => 'some text',
'created' => 'time',
'tags' => array(array('title' => 'hello')),
)
array('title' => 'Testing',
'content' => 'some text',
'created' => 'time',
'tags' => array(array('title' => 'hello')),
)
I want to merge all of these in an array of the format:
array(
array('notes' =>
array('title' => 'Testing',
'content' => 'some text',
'created' => 'time',
'tags' => array(array('title' => 'hello')),
),
),
array('notes' =>
array('title' => 'Testing',
'content' => 'some text',
'created' => 'time',
'tags' => array(array('title' => 'hello')),
),
),
);
I've tried many PHP functions but none gave me the result I want. Can someone help me please? Is there a built-in PHP function that can do this? Can someone show me an example.
Thanks.
If I'm understanding your question correctly, all you actually want to do is place each of your array elements into another array with the key notes and the value being that of the element (another array).
In which case either using foreach or array_map will do.
$newArray = array_map(function($v) { return ['notes' => $v]; }, $array);
Or using foreach (the more verbose way)...
foreach($array as $value) {
$newArray[] = ['notes' => $value];
}
this is a comment i want the formatting...
You have asked for an 'array' of 'array entries' where each entry
is an array
each array has a key of 'notes' and an associated data array.
I think the 'tags' part of you structure would be easier to use without the extra level of 'nesting'.
Here is the code to create and display the 'wanted' output with the 'tag' entry changed:
$wanted = array(
array('notes' =>
array('title' => 'Testing 1',
'content' => 'some text 1',
'created' => date('Y-m-d H:i:s'),
'tags' => array('title' => 'hello',
'tagFoo' => 'foo' ),
),
),
array('notes' =>
array('title' => 'Testing 2',
'content' => 'some text 2',
'created' => date('Y-m-d H:i:s'),
'tags' => array('title' => 'hello',
'tagBar' => 'bar'),
),
),
);
echo '<pre>';
print_r($wanted);
echo '</pre>';
Here is the output:
Array
(
[0] => Array
(
[notes] => Array
(
[title] => Testing 1
[content] => some text 1
[created] => 2015-01-04 15:39:34
[tags] => Array
(
[title] => hello
[tagFoo] => foo
)
)
)
[1] => Array
(
[notes] => Array
(
[title] => Testing 2
[content] => some text 2
[created] => 2015-01-04 15:39:34
[tags] => Array
(
[title] => hello
[tagBar] => bar
)
)
)
)
one possibilyti is to do:
foreach($tags as $key => $note){
$note["created"] = $created[$key]; //if created is an array
$note["created"] = $created; //if created is a string
}

Access an array value from a JSON response using PHP

I am new to JSON and I am having a problem accessing particular values in the JSON array that is being returned from the API call. For instance, I would like to access the name value in the response data below (these are the first two responses from the API call). I know I am missing something obvious but I can't quit get it. Any help would be appreciated:
ReadResponse::__set_state(array(
0 =>
array (
'address' => '6866 N Rochester Rd',
'category' => 'Food & Beverage > Restaurants',
'category_ids' =>
array (
0 => 347,
),
'category_labels' =>
array (
0 =>
array (
0 => 'Social',
1 => 'Food and Dining',
2 => 'Restaurants',
),
),
'country' => 'us',
'factual_id' => '8e6aacfa-b435-407d-83f9-90cec16c1cf8',
'latitude' => 42.69804075,
'locality' => 'Rochester Hills',
'longitude' => -83.134586375,
'name' => 'Sushi Little Tokyo',
'neighborhood' =>
array (
0 => '\\Livernois-Tienken\\',
),
'postcode' => '48306',
'region' => 'MI',
'status' => '1',
'tel' => '(248) 608-1260',
),
1 =>
array (
'address' => '2964 S Rochester Rd',
'category' => 'Food & Beverage > Restaurants',
'category_ids' =>
array (
0 => 347,
),
'category_labels' =>
array (
0 =>
array (
0 => 'Social',
1 => 'Food and Dining',
2 => 'Restaurants',
),
),
'country' => 'us',
'factual_id' => '35d2fc06-a941-4dbf-9dcb-204964fec730',
'latitude' => 42.636786765426,
'locality' => 'Rochester Hills',
'longitude' => -83.131888674506,
'name' => 'Pudthi and Sushi',
'postcode' => '48307',
'region' => 'MI',
'status' => '1',
'tel' => '(248) 299-6890',
'website' => 'http://www.pudthaiandsushi.com',
),
Try this PHP function json_decode() to translate your JSON response into a PHP multidimensional array where you can easily access the values in the array like
the name would be
$name = $myPHPArray->country->name;
This is the result of a var_export. The data is all contained in an instance of the ReadResponse. To find out how you can access the data, read the source or documentation of that class.

Categories