group unique values in multidimensional array - php

I have an array of RestroreModels
if the RestoreCode value exists multiple times in array. Based on unique restore I want to add the TotalCharge value and put the associated model with that RestoreCode in a new array. if the RestoreCode value exist only once put as it is with single model in array.
$RestroreModels = array (
0 =>
array (
'TotalCharge' => '3',
'RestoreCode' => 'FF 0',
'Model' => 'iPhone 7',
),
1 =>
array (
'TotalCharge' => '2',
'RestoreCode' => 'LT 2015',
'Model' => 'iPad Mini 2',
),
2 =>
array (
'TotalCharge' => '2',
'RestoreCode' => 'LT 4013',
'Model' => 'iPhone 6',
),
3 =>
array (
'TotalCharge' => '2',
'RestoreCode' => 'LT 4013',
'Model' => 'ipod touch',
),
4 =>
array (
'TotalCharge' => '2',
'RestoreCode' => 'P 21',
'Model' => 'iPhone 7',
),
5 =>
array (
'TotalCharge' => '2',
'RestoreCode' => 'AL 2015',
'Model' => 'iPhone 7',
),
6 =>
array (
'TotalCharge' => '2',
'RestoreCode' => 'AL 0',
'Model' => 'ipod touch',
),
7 =>
array (
'TotalCharge' => '1',
'RestoreCode' => 'LT 2015',
'Model' => 'iPad Mini',
),
8 =>
array (
'TotalCharge' => '1',
'RestoreCode' => 'LT 4005',
'Model' => 'iPad Mini',
),
9 =>
array (
'TotalCharge' => '1',
'RestoreCode' => 'P 21',
'Model' => 'iPad 5',
),
10 =>
array (
'TotalCharge' => '1',
'RestoreCode' => 'LT 4013',
'Model' => 'iPhone 7+',
)
);
i want the result like this
$RestroreModels = array (
0 =>
array (
'TotalCharge' => '4',
'RestoreCode' => 'LT 2015',
'Model' => array ('iPad Mini 2', 'iPhone 7')
),
1 =>
array (
'TotalCharge' => '3',
'RestoreCode' => 'LT 4013',
'Model' => array ('iPhone 7+', 'ipod touch', 'iPad Mini 2')
),
2 =>
array (
'TotalCharge' => '3',
'RestoreCode' => 'P 21',
'Model' => array ('iPad Mini 2', 'iPhone 7', 'iPad 5')
),
3 =>
array (
'TotalCharge' => '2',
'RestoreCode' => 'AL 2015',
'Model' => array ('iPhone 7'),
),
4 =>
array (
'TotalCharge' => '2',
'RestoreCode' => 'AL 0',
'Model' => array ('ipod touch'),
),
5 =>
array (
'TotalCharge' => '1',
'RestoreCode' => 'LT 4005',
'Model' => array ('iPad Mini'),
),
);
I have Tried this so far i am able to get unique values but not sure how to add add TotalCharge and put model related to RestoreCode in $final_array.
$final_array = array();
$keys_array = array();
foreach ($RestroreModels as $key => $value) {
if (!in_array($value['RestoreCode'], $keys_array)) {
$keys_array[$key] = $value['RestoreCode'];
$final_array[$key] = $value;
}
}
var_dump ($final_array);
die();

Taking the note if the RestoreCode value exist only once put as it is with single model in array into account, I think you might use a foreach loop and store the RestoreCode of a single array as the key in the result array. Note that the result will differ from your wanted result as the item with a single RestoreCode will also be in the result.
Per iteration check if that key already exists. If if does not, add it and put the value for the Model in a new array.
If it does exist, add the values for TotalCharge. To get the unique values for the Models, check if the current array for Model already contains it.
If you want to reset the keys, you could use array_values.
$res = [];
foreach ($RestroreModels as $item) {
if (isset($res[$item["RestoreCode"]])) {
if (!in_array($item["Model"], $res[$item["RestoreCode"]]["Model"], true)) {
$res[$item["RestoreCode"]]["Model"][] = $item["Model"];
}
$res[$item["RestoreCode"]]["TotalCharge"] += $item["TotalCharge"];
} else {
$item["Model"] = [$item["Model"]];
$res[$item["RestoreCode"]] = $item;
}
}
print_r(array_values($res));
Php demo

Related

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

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);

Flat array to a hierarchical multi-dimensional array

I have an flat array that looks like this exemple :
array (
0 =>
array (
'TreePad_Fields' =>
array (
'#ID' => '1',
'#NAME' => '[CDATA[nomenclature exemple]]',
'#LEVEL' => '0',
),
),
1 =>
array (
'TreePad_Fields' =>
array (
'#ID' => '3',
'#NAME' => '[CDATA[droit]]',
'#LEVEL' => '1',
),
),
2 =>
array (
'TreePad_Fields' =>
array (
'#ID' => '13',
'#NAME' => '[CDATA[législation]]',
'#LEVEL' => '2',
),
),
3 =>
array (
'TreePad_Fields' =>
array (
'#ID' => '14',
'#NAME' => '[CDATA[statuts]]',
'#LEVEL' => '3',
),
),
4 =>
array (
'TreePad_Fields' =>
array (
'#ID' => '15',
'#NAME' => '[CDATA[projets de loi]]',
'#LEVEL' => '4',
),
),
5 =>
array (
'TreePad_Fields' =>
array (
'#ID' => '16',
'#NAME' => '[CDATA[réglementations]]',
'#LEVEL' => '2',
),
),
6 =>
array (
'TreePad_Fields' =>
array (
'#ID' => '17',
'#NAME' => '[CDATA[instruments statutaires]]',
'#LEVEL' => '3',
),
),
7 =>
array (
'TreePad_Fields' =>
array (
'#ID' => '2',
'#NAME' => '[CDATA[économie]]',
'#LEVEL' => '1',
),
),
8 =>
array (
'TreePad_Fields' =>
array (
'#ID' => '8',
'#NAME' => '[CDATA[analyse cout-avantage]]',
'#LEVEL' => '2',
),
),
9 =>
array (
'TreePad_Fields' =>
array (
'#ID' => '6',
'#NAME' => '[CDATA[analyse socio-économique]]',
'#LEVEL' => '2',
),
),
)
and I would like to have like this :
$data = array(
'[CDATA[nomenclature exemple]]' => array(
'[CDATA[droit]]' => array(
'[CDATA[législation]]' => array(
'[CDATA[statuts]]' => array(
'[CDATA[projets de loi]]'
),
),
'[CDATA[réglementations]]' => array(
'[CDATA[instruments statutaires]]'
),
),
'[CDATA[économie]]' => array(
'[CDATA[analyse cout-avantage]]',
'[CDATA[analyse socio-économique]]',
),
)
);
I can't figure out how to do it. I've found other examples here for converting flattened arrays into multidimensional ones but not where there's a custom child like this.
I should say it is a bit inconsistent to want to have the leaves in the datastructure have the [CDATA...] name as value of an indexed array, while in the rest of the tree they are keys.
So, I would suggest to make those leaves also keyed by the [CDATA...] name, but just with an empty array as value. That way the structure is consistent throughout.
For that structure you could use this function:
function buildTree($data) {
foreach($data as $i => $row) {
$arr = $row['TreePad_Fields'];
$level = $arr['#LEVEL'];
$key = $arr['#NAME'];
$levels[$level][$key] = [];
$levels[$level+1] = &$levels[$level][$key];
}
return $levels[0];
}
Call it like this:
$result = buildTree($data);
For the sample data given, the result would be:
array (
'[CDATA[nomenclature exemple]]' => array (
'[CDATA[droit]]' => array (
'[CDATA[législation]]' => array (
'[CDATA[statuts]]' => array (
'[CDATA[projets de loi]]' => array (),
),
),
'[CDATA[réglementations]]' => array (
'[CDATA[instruments statutaires]]' => array (),
),
),
'[CDATA[économie]]' => array (
'[CDATA[analyse cout-avantage]]' => array (),
'[CDATA[analyse socio-économique]]' => array (),
),
),
)
See it run on eval.in

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;

PHP merge associative arrays by replacing same keys and adding new

I have an array of variable size structured like this (categories is only one of the keys inside data):
print_r($json[123]["data"]["categories"]);
array(
array(
'id' => '2',
'description' => 'Single-player'
),
array(
'id' => '1',
'description' => 'Multi-player'
),
array(
'id' => '9',
'description' => 'Co-op'
),
array(
'id' => '22',
'description' => 'Steam Achievements'
),
array(
'id' => '28',
'description' => 'Full controller support'
)
)
print_r($json[456]["data"]["categories"]);
array(
array(
'id' => '21',
'description' => 'Downloadable Content'
),
array(
'id' => '1',
'description' => 'Multi-player'
)
)
Now, I want to merge these sub-arrays (they can be in variable number) and have all keys added and replaced. I've tried array_merge but it replaces the keys without adding new ones.
In this case I need to obtain this array:
print_r($merged["data"]["categories"]);
array(
array(
'id' => '2',
'description' => 'Single-player'
),
array(
'id' => '1',
'description' => 'Multi-player'
),
array(
'id' => '9',
'description' => 'Co-op'
),
array(
'id' => '22',
'description' => 'Steam Achievements'
),
array(
'id' => '28',
'description' => 'Full controller support'
),
array(
'id' => '21',
'description' => 'Downloadable Content'
)
)
Any help?
Edit:
I think I didn't expressed myself well enough. $json[$id]["data"] has multiple keys I want to merge (categories is just an example). Also the number of $json[$id] keys is variable
Edit2:
The arrays can have duplicate values, and the depth of the keys can be variable. I need to get something like array_merge_recursive() but with same values replaced.
Edit3:
This is the current array. http://pastebin.com/7x7KaAVM I need to merge all keys that have sub-arrays
Try below code:
$json = array(
'123' => array('data' => array('categories' => array(
array(
'id' => '2',
'description' => 'Single-player'
),
array(
'id' => '1',
'description' => 'Multi-player'
),
array(
'id' => '9',
'description' => 'Co-op'
),
array(
'id' => '22',
'description' => 'Steam Achievements'
),
array(
'id' => '28',
'description' => 'Full controller support'
)
))
),
'456' => array('data' => array('categories' => array(
array(
'id' => '21',
'description' => 'Downloadable Content'
)
))
),
);
//print_r($json);
$merged = array();
foreach($json as $j1)
{
foreach($j1 as $j2)
{
foreach($j2 as $key => $j3)
{
foreach($j3 as $j4)
{
$merged[$key][] = $j4;
}
}
}
}
print_r($merged);
Result:
Array
(
[categories] => Array
(
[0] => Array
(
[id] => 2
[description] => Single-player
)
[1] => Array
(
[id] => 1
[description] => Multi-player
)
[2] => Array
(
[id] => 9
[description] => Co-op
)
[3] => Array
(
[id] => 22
[description] => Steam Achievements
)
[4] => Array
(
[id] => 28
[description] => Full controller support
)
[5] => Array
(
[id] => 21
[description] => Downloadable Content
)
)
)
Demo:
http://3v4l.org/X61bE#v430
Try this . To generalize I have added some more arrays.
<?php
$merged_array = array();
$final_array = array();
$json[123]["data"]["categories"] = array(
array(
'id' => '2',
'description' => 'Single-player'
),
array(
'id' => '1',
'description' => 'Multi-player'
),
array(
'id' => '9',
'description' => 'Co-op'
),
array(
'id' => '22',
'description' => 'Steam Achievements'
),
array(
'id' => '28',
'description' => 'Full controller support'
)
);
$json[456]["data"]["categories"] = array(
array(
'id' => '21',
'description' => 'Downloadable Content'
)
);
$json[786]["data"]["categories"] = array(
array(
'id' => '31',
'description' => 'Downloadable Content'
)
);
$json[058]["data"]["categories"] = array(
array(
'id' => '41',
'description' => 'Downloadable Content'
)
);
foreach($json as $key=>$value){
array_push($merged_array,$json[$key]["data"]["categories"]);
}
foreach($merged_array as $value){
foreach($value as $val){
array_push($final_array,$val);
}
}
print_r($final_array);
?>
RESULT
Array
(
[0] => Array
(
[id] => 2
[description] => Single-player
)
[1] => Array
(
[id] => 1
[description] => Multi-player
)
[2] => Array
(
[id] => 9
[description] => Co-op
)
[3] => Array
(
[id] => 22
[description] => Steam Achievements
)
[4] => Array
(
[id] => 28
[description] => Full controller support
)
[5] => Array
(
[id] => 21
[description] => Downloadable Content
)
[6] => Array
(
[id] => 31
[description] => Downloadable Content
)
[7] => Array
(
[id] => 41
[description] => Downloadable Content
)
)

changing array id in an multidimensional array with another array in php

I have 2 arrays:
$myArray = array ( 'name' => 'Dollar', 'sign' => '$', 'format' => '1', 'decimals' => '1', 'conversion_rate' => '1.324400' );
$myArrayNew = array ( 0 => 'Name', 1 => 'Sign', 2 => 'Format', 3 => 'Decimals', 4 => 'Conversion Rate');
When i use
$combinedarrays = array_combine($myArrayNew, $myArray);
the output is
Array ( [Name] => Dollar [Sign] => $ [Format] => 1 [Decimals] => 1 [Conversion Rate] => 1.324400 )
That is what I need, but the problem is when my first array is multidimensional like:
$myArray = array( array ( 'name' => 'Dollar', 'sign' => '$', 'format' => '1', 'decimals' => '1', 'conversion_rate' => '1.324400' ),
array ( 'name' => 'Euro', 'sign' => '€', 'format' => '2', 'decimals' => '1', 'conversion_rate' => '1.000000' ));
So, how to change the keys to be like below?
$myArray = array( array ( 'Name' => 'Dollar', 'Sign' => '$', 'Format' => '1', 'Decimals' => '1', 'Conversion Rate' => '1.324400' ),
array ( 'Name' => 'Euro', 'Sign' => '€', 'Format' => '2', 'Decimals' => '1', 'Conversion Rate' => '1.000000' ));
You need to loop on sub arrays.
Try this:
$myArrayNew = array ( 0 => 'Name', 1 => 'Sign', 2 => 'Format', 3 => 'Decimals', 4 => 'Conversion Rate');
$myArray = array( array ( 'name' => 'Dollar', 'sign' => '$', 'format' => '1', 'decimals' => '1', 'conversion_rate' => '1.324400' ),
array ( 'name' => 'Euro', 'sign' => '€', 'format' => '2', 'decimals' => '1', 'conversion_rate' => '1.000000' ));
$combinedarrays = array();
foreach($myArray as $subarr)
$combinedarrays[] = array_combine($myArrayNew, $subarr);
print_r($combinedarrays);

Categories