Create new JSON with sum of values in array - php

I have below array,
Array ( [0] => Array ( [user_name] => Jack1 [amount] => 100.00 [category_name] => Trial1 ) [1] => Array ( [user_name] => Jack1 [amount] => 150.00 [category_name] => Trial2 ) [2] => Array ( [user_name] => Jack1 [amount] => 200.00 [category_name] => Trial1 ) [3] => Array ( [user_name] => Jack2 [amount] => 200.00 [category_name] => Trial2 ) [4] => Array ( [user_name] => Jack2 [amount] => 200.00 [category_name] => Trial1 ) [5] => Array ( [user_name] => Jack2 [amount] => 200.00 [category_name] => Trial2 )
What i want to send to have JSON with below format
It will get some of Equal category name and then send it as json.
[{'user_name': Jack1, 'trial1':"300", 'trial2':150"" }, {'user_name': Jack2, 'trial1':"200", 'trial2':400"" }]
In summary, i want to username as unique and then put all category with name and sum of each category for that user,
Tried below,
$new_array = array();
foreach ($expense_array['x'] as $a)
{
if (!isset($new_array[$a['user_name']]['amount']))
{
$new_array[$a['user_name']]['amount'] = 0;
}
$new_array[$a['user_name']] = array(
'user_name' => $a['user_name'],
'category_name' => $a['category_name'],
'amount' => $new_array[$a['user_name']]['amount'] + $a['amount']);
}
echo json_encode(array_values($new_array));
This only output trai1 category, not as required JSON
How can i achieve this?
Was thinking to get foreach loop and then make compare of category_name and use .=+ to get sum? but i lost there,
Thanks,

If you pass the array into this function it will return the json string that you want:
function create_json($data)
{
$output = [];
foreach ( $data as $stats )
{
$key = $stats['user_name'];
$category = strtolower($stats['category_name']);
$amount = $stats['amount'];
if ( isset($output[$key]) )
{
if ( isset($output[$key][$category]) )
{
$output[$key][$category] += $amount;
}
else
{
$output[$key][$category] = $amount;
}
}
else
{
$output[$key] = [
'user_name' => $key,
$category => $amount,
];
}
}
return json_encode(array_values($output));
}
Output:
[
{"user_name":"Jack1","trial1":300,"trial2":150},
{"user_name":"Jack2","trial2":400,"trial1":200}
]

Related

How to iterate values in foreach and create array with new values in cakephp 3.x

I have below code from which i am getting Below data in response..
public function getCategory(){
$this->autoRender = False;
$list = TableRegistry::get('Subproducts');
$supplierId = $this->request->data['supplierId'];
if($this->request->is('ajax')) {
if(!empty($supplierId)) {
$query1 = $list->find()->contain(['Products'])
->where(['Subproducts.supplier_id =' => $supplierId]);
$data = $query1->hydrate(false)->toArray();
if(!empty($data)){
**Print_r($data);**
**foreach ($data as $value){
print_r($value);
}**
//echo json_encode(array("category"=>$newArray));
exit;
}
}
}
}
Below Data i am getting from above code
Array
(
[supplier_id] => 40
[product] => Array
(
[id] => 45
[name] => PLASTIC ITEM
[is_deleted] => 0
)
)
Array
(
[supplier_id] => 40
[product] => Array
(
[id] => 50
[name] => RAW MATERIAL
[is_deleted] => 0
)
)
I want to collect Id and Name of product array in $newArray, but i am not able to iterate product array and dont know how to add id and name of product in $newArray. Can anyone please help me to iterate product array value and create new array which contains only Id and Name.
I need help inside to iterate values and create new array with only id and name of product array.
**Print_r($data) is getting below data, I have added print_r($data); like below code, i mean before foreach loop..
if(!empty($data)){
print_r($data);
foreach ($data as $value) { }
}
Array
(
[0] => Array
(
[id] => 468
[supplier_id] => 40
[buy_price] => 6.23
[sell_price] => 7.87
[category_id] => 45
[product_name] => test1
[is_deleted] => 0
[created] => Cake\I18n\FrozenTime Object
(
[date] => 2021-10-12 09:48:20.000000
[timezone_type] => 3
[timezone] => UTC
)
)
[1] => Array
(
[id] => 469
[supplier_id] => 40
[buy_price] => 44.89
[sell_price] => 7.87
[category_id] => 50
[product_name] => test
[is_deleted] => 0
[created] => Cake\I18n\FrozenTime Object
(
[date] => 2021-10-12 11:44:28.000000
[timezone_type] => 3
[timezone] => UTC
)
)
)
Loop over the inner array and grab the parts you are interested in from there
UPDATE: Ok so it looks like the array is not inside another so a simple foreach will do it
$newArray = []; // initialise the array
foreach ($data as $inner) {
$newArray[] = [ 'id' => $inner['product']['id'],
'name' => $inner['product']['name']
]
}
$newArray = []; // initialise the array
foreach ($data as $key=> $value) {
$newArray[] = [
'id' => $value['product']['id'],
'name' => $value['product']['name']
];
}

How to Sum Array Associative with 2 key values

I'm try to Sum values with 2 keys condition in associative array, but didn't get any result and only not like expected.
my array:
Array
(
[0] => Array
(
[pid] => P1
[rid] => 1
[price] => 100
)
[1] => Array
(
[pid] => P1
[rid] => 1
[price] => 120
)
[2] => Array
(
[pid] => P1
[rid] => 1
[price] => 130
)
[3] => Array
(
[pid] => P2
[rid] => 1
[price] => 80
)
[4] => Array
(
[pid] => P2
[rid] => 1
[price] => 120
)
[5] => Array
(
[pid] => P2
[rid] => 2
[price] => 150
)
);
i have tried some code from
How to GROUP BY and SUM PHP Array? or Grouping arrays in PHP
and then the code becomes:
$groups = array();
foreach ($array as $item) {
$key = $item['pid'];
if (!array_key_exists($key,$groups)) {
$groups[$key] = array(
'pid' => $item['pid'],
'rid'=>$item['rid'],
'price' => $item['price']
);
} else {
$groups[$key]['price'] += $item['price'];
}
}
i exptected output array:
Array
(
[0] => Array
(
[pid] => P1
[rid] => 1
[price] => 350
)
[1] => Array
(
[pid] => P2
[rid] => 1
[price] => 200
)
[2] => Array
(
[pid] => P2
[rid] => 2
[price] => 150
)
);
I have no idea how to write with array_reduce as well as foreach to resolve this, please hit me by other refrence or help me to solve this.
If $data is your input array, you can use below code
$r = array();
foreach ( $data as $d ) {
$key = $d['pid'] . '-' . $d['rid'];
if( !isset ( $r[$key] ) ) {
$r[$key] = $d;
} else {
$r[$key]['price'] += $d['price'];
}
}
echo '<pre>';
print_r($r);
die;

Remove duplicates array

I have an array looks like this,
Array
(
[0] => Array
(
[id] => 224983
[name] => James
[weight] => 0
[bank] => Bank A
[transaction] => 1
[total] => 7682000000
[reference] => Edward
[type] => BRANCH
[reference_id] => 222818
[account_number] => 1220007355285
)
[1] => Array
(
[id] => 224984
[name] => James
[weight] => 0
[bank] => Bank A
[transaction] => 1
[total] => 7682000000
[reference] => Edward
[type] => BRANCH
[reference_id] => 222819
[account_number] => 1220007355285
)
[3] => Array
(
[id] => 224985
[name] => Maria
[weight] => 0
[bank] => Bank B
[transaction] => 1
[total] => 1500000000
[reference] => Andrey
[type] => BRANCH
[reference_id] => 247620
[account_number] => 1220000412901
)
)
When the account_number, reference, and name is same I want to remove the other one, and keep the last based on id...
Please someone help me to find out, I've been stuck here, so the output would be remove array[0] with ['id] => 224983, and the rest array would be the result
If you specifically just want to compare only three field of array than you can try below way. Which checks of duplicate and unset previous entries. Here $data is array input
foreach ($data as $key => $row) {
$id = $row['id'];
$name = $row['name'];
$reference = $row['reference'];
$flag = 0;
for($i = $key + 1; $i < count($data); $i++)
{
if(($data[$i]['id'] == $id) && ($data[$i]['name'] == $name) && ($data[$i]['reference'] == $reference))
{
if($key != $i)
unset($data[$key]);
}
}
}
Result would be
Array
(
[1] => Array
(
[id] => 224983
[name] => James
[weight] => 0
[bank] => Bank A
[transaction] => 1
[total] => 7682000000
[reference] => Edward
[type] => BRANCH
[reference_id] => 222818
[account_number] => 1220007355285
)
[2] => Array
(
[id] => 224985
[name] => Maria
[weight] => 0
[bank] => Bank B
[transaction] => 1
[total] => 1500000000
[reference] => Andrey
[type] => BRANCH
[reference_id] => 247620
[account_number] => 1220000412901
)
)
Try the following function, This will help to remove duplicates arrays.
function array_unique_multidimensional($input)
{
$serialized = array_map('serialize', $input);
$unique = array_unique($serialized);
return array_intersect_key($input, $unique);
}
It seems inelegant, but I think you would need to loop through your previous array elements to check IDs. You could create a function something like this:
function id_exists_prior(&$my_array, $array_index) {
for($i = 0; $i < $array_index; $i++) {
if($my_array[$i]['id'] === $my_array[$array_index]['id']) return false;
}
return true;
}
Then you can call it on any array element you wish, or loop through the whole array to check for duplicates. An example of the latter:
$your_array = [/*Your array data*/];
for($key = 0; $key < count($your_array); $key++) {
if(id_exists_prior($your_array, $key)) //Do your thing
}
The reason for passing the array key into the function is so that the function ONLY checks for prior duplicates.
Hope this helps!

PHP Array re-arrange to Multi Dimensional

I have an array structure like this and wanted to Re-arrange it to the one below. Any suggestions for a faster/simple fix? I already did the addition of the dates. Thanks! :)
Input:
Array
(
[0] => Array
(
[user_id] => 255
[display_name] => Mark
[company_name] => Company_A
)
[1] => Array
(
[user_id] => 150
[display_name] => Paul
[company_name] => Company_A
)
[2] => Array
(
[user_id] => 25
[display_name] => Hulk
[company_name] => Company_B
)
[3] => Array
(
[user_id] => 50
[display_name] => Bob
[company_name] => Company_B
)
)
Output:
Array
(
[Company_A] => Array
(
[company_total_hours] => 20h 45m
[employees] => Array
(
[0] => Array
(
[user_id] => 255
[display_name] => Mark
)
[1] => Array
(
[user_id] => 150
[display_name] => Paul
)
)
)
[Company_B] => Array
(
[company_total_hours] => 7h 30m
[employees] => Array
(
[0] => Array
(
[user_id] => 25
[display_name] => Hulk
)
[1] => Array
(
[user_id] => 50
[display_name] => Bob
)
)
)
)
My Attempts:
<?php
$company_names = array();
foreach ($records as $k => $v) {
$company_names[] = $v->company_name;
}
$company_names = array_unique($company_names);
// hard coded testing
if (count($company_names) > 0) {
foreach($company_names as $k2 => $v2) {
$final_array[$v2]['company_total_hours'] = rand(1, 20);
$final_array[$v2]['employees'] = array(
array('user_id' => '255', 'display_name' => 'Mark'),
array('user_id' => '150', 'display_name' => 'Paul')
);
}
}
// on-going testing right now here....
I don't see where you derive your hours from so I left that out.
$i = 0;
foreach($vals as $keys => $arrays) {
if(!isset($new[$arrays['company_name']]))
$i = 0;
$new[$arrays['company_name']]['employees'][$i]['display_name'] = $arrays['display_name'];
$new[$arrays['company_name']]['employees'][$i]['user_id'] = $arrays['user_id'];
$i++;
}
Gives you:
Array
(
[Company_A] => Array
(
[employees] => Array
(
[0] => Array
(
[display_name] => Mark
[user_id] => 255
)
[1] => Array
(
[display_name] => Paul
[user_id] => 150
)
)
)
[Company_B] => Array
(
[employees] => Array
(
[0] => Array
(
[display_name] => Hulk
[user_id] => 25
)
[1] => Array
(
[display_name] => Bob
[user_id] => 50
)
)
)
)
foreach($arr as $v)
{
if(!$arr2[$v['company_name']]['employees'])
$arr2[$v['company_name']]['employees'] = array();
if(!$arr2[$v['company_name']]['company_total_hours'])
$arr2[$v['company_name']]['company_total_hours'] = '2h';//addional value
$arr2[$v['company_name']]['employees'][] = array('user_id'=>$v['user_id'],
'display_name'=>$v['display_name']
);
}
I have created a function which does the same thing as the answer given by #Rasclatt.
function groupByKeyValue($array, $oldKeyName, $newKeyName){
$newArray = array();
foreach($array as $key=>$value){
if(isset($newArray[$value[$oldKeyName]][$newKeyName])){
$newArray[$value[$oldKeyName]][$newKeyName][] = array('user_id'=> $value['user_id'], 'display_name' => $value['display_name']);
}else{
$newArray[$value[$oldKeyName]] = array($newKeyName => array(array('user_id'=> $value['user_id'], 'display_name' => $value['display_name'])));
}
}
return $newArray;
}
//usage
$newArray = groupByKeyValue($array, 'company_name', 'employees');
You can add a third parameter to send the keys for the array values which needs to be used in the new array for 'employees'. Please check this link for the working of the function http://goo.gl/I6Of5y

sorting data from an array on php

i'm deploying a shipping service to shopify using a webhook to get this data converted in json, i trying to send only the fields name, quantity, sku and id in a table.
i'm using foreach function to make it but no results.
Grettings!
[fulfillments] => Array
(
[0] => stdClass Object
(
[line_items] => Array
(
[0] => stdClass Object
(
[fulfillment_service] => manual
[fulfillment_status] => fulfilled
[gift_card] =>
[grams] => 2000
[id] => 470651995
[price] => 200.00
[product_id] => 304163215
[quantity] => 1
[requires_shipping] => 1
[sku] => 123456789
[taxable] =>
[title] => Product 1
[variant_id] => 709836495
[variant_title] =>
[vendor] => kkk
[name] => Product 1
)
[1] => stdClass Object
(
[fulfillment_service] => manual
[fulfillment_status] => fulfilled
[gift_card] =>
[grams] => 2000
[id] => 470651995
[price] => 200.00
[product_id] => 304163215
[quantity] => 3
[requires_shipping] => 1
[sku] => 123456789
[taxable] =>
[title] => Product 2
[variant_id] => 709836495
[variant_title] =>
[vendor] => kkk
[name] => Product 2
)
)
)
)
$your_array = json_decode(json_encode($your_array), true);
//it will casts from StdClass to an array
$your_array = $your_array['fulfillments'];
$result_array = array();
$yaCnt = count($your_array);
for($i = 0; $i < $yaCnt; ++$i)
{
$items = $yaCnt[$i]['line_items'];
$iCnt = count($items);
for($j = 0; $j < $iCnt; ++$j)
{
$result_array[] = array(
'name' => $items[$j]['name'],
'quantity' => $items[$j]['quantity'],
'sku' => $items[$j]['sku'],
'id' => $items[$j]['id']
);
}
}
print_r($result_array);
Try the following foreach(), I have assumed you store all the initial data in the variable $fulfillments
$items = array();
foreach($fulfillments[0]->line_items as $item)
{
$items[] = array(
"name" => $item->name,
"quantity" => $item->quantity,
"sku" => $item->sku,
"id" => $item->id
);
}
echo json_encode($items);
<?php
$yourData = array();
$shippingData =array();
foreach ($yourData as $fulfillments) {
foreach ($fulfillments->line_items as $line_items) {
$shippingData[] = array(
'name' => $line_items->name,
'quantity' => $line_items->quantity,
'sku' => $line_items->sku,
'id' => $line_items->id
);
}
}
echo json_encode($shippingData);

Categories