How to generate array from an array - php

I have an array but I want to generate other array from that one..
Array
(
[0] => Array
(
[supplier] => Billy
[total_bookings] => 5
[year] => 2016
[month] => 6
[user_id] => 4
[sales_revenue] => 1180
[net_revenue] => 1180
)
[1] => Array
(
[supplier] => XYZ1
[total_bookings] => 3
[year] => 2016
[month] => 6
[user_id] => 2
[sales_revenue] => 642
[net_revenue] => 642
)
[2] => Array
(
[supplier] => Billy
[total_bookings] => 1
[year] => 2016
[month] => 3
[user_id] => 4
[sales_revenue] => 30
[net_revenue] => 30
)
[3] => Array
(
[supplier] => Billy
[total_bookings] => 1
[year] => 2015
[month] => 10
[user_id] => 4
[sales_revenue] => 30
[net_revenue] => 30
)
)
to new array :
Array
(
[2016] => Array(
[6] => Array
(
[0] => Array(
[supplier] => Billy
[total_bookings] => 5
[user_id] => 4
[sales_revenue] => 1180
[net_revenue] => 1180
)
[1] => Array
(
[supplier] => XYZ1
[total_bookings] => 3
[user_id] => 2
[sales_revenue] => 642
[net_revenue] => 642
)
)
[3] => Array
(
[0] => Array
(
[supplier] => Billy
[total_bookings] => 1
[year] => 2016
[month] => 3
[user_id] => 4
[sales_revenue] => 30
[net_revenue] => 30
)
)
)
[2015] => Array(
[10] => Array
(
[supplier] => Billy
[total_bookings] => 1
[user_id] => 4
[sales_revenue] => 30
[net_revenue] => 30
)
)
)

The solution using array_fill_keys, array_column(available since PHP 5.5), array_walk and array_diff_key functions:
// supposing $arr is your initial array
$years = array_fill_keys(array_column($arr, 'year'), []);
array_walk($arr, function($v) use(&$years){
if (key_exists($v['year'], $years)) {
$years[$v['year']][$v['month']][] = array_diff_key($v, ['year'=>0, 'month'=>0]);
}
});
print_r($years);

Try this one and let me know:
$new_arr = array();
foreach($arr as $val){
$temp = array('supplier' => $val['supplier'], 'total_bookings' => $val['total_bookings'], 'user_id' => $val['user_id'], 'sales_revenue' => $val['sales_revenue'], 'net_revenue' => $val['net_revenue']);
array_push($new_arr[$val['year']][$val['month']], $temp);
}
print_r($new_arr);

Try this one:-
$res = [];
foreach($array as $record){
$year = $record['year'];
$month = $record['month'];
unset($record['year'],$record['month']);
$res[$year][$month][] = $record;
}
echo '<pre>'; print_r($res);

Related

Group multidimensional arrays by key

I'm stuck on this problem and I hope someone can help me on that.
I have an array which I want to group by a specific key. The only problem is that I want to have a new array whenever the value of the key changes during the loop. Here is an example of the array.
Array
(
[0] => Array
(
[id] => 972
[user_id] => 2
[user_field_48] => 1
[project] => 100 — NLO
[duration] => 1:00
[grouped_by] => 1
)
[1] => Array
(
[id] => 644
[user_id] => 2
[user_field_48] => 4
[project] => 123 — QHV
[duration] => 15:00
[grouped_by] => 4
)
[2] => Array
(
[id] => 631
[user_id] => 2
[user_field_48] => 4
[project] =>
[duration] => -5:00
[grouped_by] => 4
)
[3] => Array
(
[id] => 630
[user_id] => 2
[user_field_48] => 1
[project] =>
[duration] => 22:00
[grouped_by] => 1
)
[4] => Array
(
[id] => 971
[user_id] => 2
[user_field_48] => 1
[project] => 100 — NLO
[duration] => 1:00
[grouped_by] => 1
)
[5] => Array
(
[id] => 973
[user_id] => 2
[user_field_48] => 1
[project] => 100 — NLO
[duration] => 1:00
[grouped_by] => 1
)
[6] => Array
(
[id] => 974
[user_id] => 2
[user_field_48] => 1
[project] => 100 — NLO
[duration] => 1:00
[grouped_by] => 1
)
)
I did
foreach($report_items as $item)
{
$groupedItems[$item['grouped_by']][] = $item;
}
and I got
Array
(
[1] => Array
(
[0] => Array
(
[id] => 972
[user_id] => 2
[user_field_48] => 1
[project] => 100 — NLO
[duration] => 1:00
[grouped_by] => 1
)
[1] => Array
(
[id] => 630
[user_id] => 2
[user_field_48] => 1
[project] =>
[duration] => 22:00
[grouped_by] => 1
)
[2] => Array
(
[id] => 971
[user_id] => 2
[user_field_48] => 1
[project] => 100 — NLO
[duration] => 1:00
[grouped_by] => 1
)
[3] => Array
(
[id] => 973
[user_id] => 2
[user_field_48] => 1
[project] => 100 — NLO
[duration] => 1:00
[grouped_by] => 1
)
[4] => Array
(
[id] => 974
[user_id] => 2
[user_field_48] => 1
[project] => 100 — NLO
[duration] => 1:00
[grouped_by] => 1
)
)
[4] => Array
(
[0] => Array
(
[id] => 644
[user_id] => 2
[user_field_48] => 4
[project] => 123 — QHV
[duration] => 15:00
[grouped_by] => 4
)
[1] => Array
(
[id] => 631
[user_id] => 2
[user_field_48] => 4
[project] =>
[duration] => -5:00
[grouped_by] => 4
)
)
)
What I'm actually looking for is something like this, where the arrays are separated during the loop and a suffix is added to the key whenever the value changes.
Array
(
[1.1] => Array
(
[0] => Array
(
[id] => 972
[user_id] => 2
[user_field_48] => 1
[project] => 100 — NLO
[duration] => 1:00
[grouped_by] => 1
)
)
[4.1] => Array
(
[0] => Array
(
[id] => 644
[user_id] => 2
[user_field_48] => 4
[project] => 123 — QHV
[duration] => 15:00
[grouped_by] => 4
)
[1] => Array
(
[id] => 631
[user_id] => 2
[user_field_48] => 4
[project] =>
[duration] => -5:00
[grouped_by] => 4
)
)
[1.2] => Array
(
[0] => Array
(
[id] => 630
[user_id] => 2
[user_field_48] => 1
[project] =>
[duration] => 22:00
[grouped_by] => 1
)
[1] => Array
(
[id] => 971
[user_id] => 2
[user_field_48] => 1
[project] => 100 — NLO
[duration] => 1:00
[grouped_by] => 1
)
[2] => Array
(
[id] => 973
[user_id] => 2
[user_field_48] => 1
[project] => 100 — NLO
[duration] => 1:00
[grouped_by] => 1
)
[3] => Array
(
[id] => 974
[user_id] => 2
[user_field_48] => 1
[project] => 100 — NLO
[duration] => 1:00
[grouped_by] => 1
)
)
)
I'm not really aware of a simple way to solve this, so I would appreciate any help. Thank you!
Not going to bother to recreate your full array here, I am using a reduced version with just the id and the grouped_by value, but the principle is of course exactly the same if you do it with your "full" array.
I am using a counter array to keep track of which "iteration" of a specific group we are currently dealing with. In classic control break implementation logic, I am comparing the grouped_by of the current record, with that of the previous one - if those differ, then the counter for this grouped_by value has to be incremented by 1. And then, I am simply creating the array key to use, by combining the grouped_by value, and the current count for it.
$data = [['id' => 972, 'grouped_by' => 1], ['id' => 664, 'grouped_by' => 4], ['id' => 631, 'grouped_by' => 4], ['id' => 630, 'grouped_by' => 1], ['id' => 971, 'grouped_by' => 1], ['id' => 973, 'grouped_by' => 1], ['id' => 974, 'grouped_by' => 1]];
$grouped_result = $grouped_by_counts = [];
$previous_grouped_by = null; // a value that will never occur in the data
foreach($data as $datum) {
if($datum['grouped_by'] !== $previous_grouped_by) {
$grouped_by_counts[$datum['grouped_by']] =
isset($grouped_by_counts[$datum['grouped_by']]) ?
$grouped_by_counts[$datum['grouped_by']] + 1 : 1;
}
$grouped_result[
$datum['grouped_by'].'.'.$grouped_by_counts[$datum['grouped_by']]
][] = $datum;
$previous_grouped_by = $datum['grouped_by'];
}
print_r($grouped_result);
Live example: https://3v4l.org/odtie

PHP Subtract multidimensional arrays based on 2 values

I need to subtract the qt from two arrays based on id and type, keeping the array complete.
How do I do in php to be able to subtract these arrays?
I have 2 arrays:
=> this is the first array with multiple key "down"
Array
(
[0] => Array
(
[id] => 26
[loc] => 1
[type] => down
[qt] => 12
)
[1] => Array
(
[id] => 32
[loc] => 1
[type] => down
[qt] => 34
)
[2] => Array
(
[id] => 26
[loc] => 2
[type] => down
[qt] => 5
)
[3] => Array
(
[id] => 86
[loc] => 3
[type] => down
[qt] => 45
)
[4] => Array
(
[id] => 23
[loc] => 9
[type] => down
[qt] => 3
)
[5] => Array
(
[id] => 23
[loc] => 3
[type] => down
[qt] => 99
)
)
=> this is the second array with multiple key "up"
Array
(
[0] => Array
(
[id] => 26
[loc] => 1
[type] => up
[qt] => 5
)
[1] => Array
(
[id] => 86
[loc] => 3
[type] => up
[qt] => 27
)
[2] => Array
(
[id] => 23
[loc] => 9
[type] => up
[qt] => 3
)
)
=> I need cubtract "qt" (if "id" and "loc" are the same then subtract the "qt")
Array
(
[0] => Array
(
[id] => 26
[loc] => 1
[type] => total
[qt] => 7
)
[1] => Array
(
[id] => 32
[loc] => 1
[type] => total
[qt] => 34
)
[2] => Array
(
[id] => 26
[loc] => 2
[type] => total
[qt] => 5
)
[3] => Array
(
[id] => 86
[loc] => 3
[type] => total
[qt] => 18
)
[4] => Array
(
[id] => 23
[loc] => 9
[type] => total
[qt] => 0
)
[5] => Array
(
[id] => 23
[loc] => 3
[type] => down
[qt] => 99
)
)
Try this out
function findMatch($array, $id, $loc)
{
foreach ($array as $key => $item) {
if ($item["id"] == $id and $item["loc"] == $loc) {
return $key;
}
}
return false;
}
$total = [];
foreach($down as $d) {
$matched = findMatch($up, $d["id"], $d["loc"]);
if($matched !== false){
$total[] = array_replace($d, [
"type" => "total",
"qt" => ($d["qt"] - $up[$matched]["qt"])
]);
} else {
$total[] = array_replace($d, ["type" => "total"]);
}
}
print_r($total);

How to get sum of array values according to some index (non-sorted)

I want the sum of monthly_rental and arc if the month and full_name are the same in one array.
Input Array
Array
(
[0] => Array
(
[0] => Array
(
[id] => 521
[full_name] => Nilesh chauhan
[monthly_rental] => 15000
[arc] => 180000
[month] => 1
)
)
[1] => Array
(
[0] => Array
(
[id] => 1549
[full_name] => Ritesh shah
[monthly_rental] => 14166.666666667
[arc] => 170000
[month] => 2
)
[1] => Array
(
[id] => 589
[full_name] => Gajanan satpute
[monthly_rental] => 14166.666666667
[arc] => 170000
[month] => 2
)
[2] => Array
(
[id] => 521
[full_name] => Nilesh chauhan
[monthly_rental] => 13333.333333333
[arc] => 160000
[month] => 2
)
[3] => Array
(
[id] => 1549
[full_name] => Ritesh shah
[monthly_rental] => 11250
[arc] => 135000
[month] => 2
)
[4] => Array
(
[id] => 521
[full_name] => Nilesh chauhan
[monthly_rental] => 7500
[arc] => 90000
[month] => 2
)
[5] => Array
(
[id] => 1549
[full_name] => Ritesh shah
[monthly_rental] => 7000
[arc] => 84000
[month] => 2
)
)
[2] => Array
(
[0] => Array
(
[id] => 1549
[full_name] => Ritesh shah
[monthly_rental] => 35833.333333333
[arc] => 430000
[month] => 3
)
[1] => Array
(
[id] => 1549
[full_name] => Ritesh shah
[monthly_rental] => 14166.666666667
[arc] => 170000
[month] => 3
)
[2] => Array
(
[id] => 521
[full_name] => Nilesh chauhan
[monthly_rental] => 13333.333333333
[arc] => 160000
[month] => 3
)
[3] => Array
(
[id] => 521
[full_name] => Nilesh chauhan
[monthly_rental] => 8750
[arc] => 105000
[month] => 3
)
[4] => Array
(
[id] => 589
[full_name] => Gajanan satpute
[monthly_rental] => 7500
[arc] => 90000
[month] => 3
)
[5] => Array
(
[id] => 1549
[full_name] => Ritesh shah
[monthly_rental] => 6493.3333333333
[arc] => 77920
[month] => 3
)
)
)
There are 6 sub-arrays in 1st and 2-nd indexes, I want the sum of 0,1,5 (Ritesh Shah, Month 2) array and make them unique. Same as this I have a long list of the array but I will manage them all if any of you just suggest to me how to get sum value of this array.
OUTPUT That I want :
Array
(
[0] => Array
(
[0] => Array
(
[id] => 521
[full_name] => Nilesh chauhan
[monthly_rental] => 15000
[arc] => 180000
[month] => 1
)
)
[1] => Array
(
[0] => Array
(
[id] => 1549
[full_name] => Ritesh shah
[monthly_rental] => 32416.66
[arc] => 389000
[month] => 2
)
[1] => Array
(
[id] => 589
[full_name] => Gajanan satpute
[monthly_rental] => 14166.666666667
[arc] => 170000
[month] => 2
)
[2] => Array
(
[id] => 521
[full_name] => Nilesh chauhan
[monthly_rental] => 20833.33
[arc] => 250000
[month] => 2
)
)
...
You can apply this function and retrieve your expected output:
function getCustomMonoRecords($data){
$res = [];
foreach($data as $m=>$ar){
$res[$m] = [];
$tmp = [];
$i = 0;
foreach($ar as $ind=>$rec){
if(!array_key_exists($rec['id'],$tmp)) {
$tmp[$rec['id']] = $i;
$res[$m][$i] = $rec;
$i++;
} else {
$in = $tmp[$rec['id']];
$res[$m][$in]['monthly_rental'] += $rec['monthly_rental'];
$res[$m][$in]['arc'] += $rec['arc'];
}
}
}
return $res;
}
Demo
Or a little bit different:
function getCustomMonoRecords2($data){
$res = [];
foreach($data as $m=>$ar){
$res[$m] = [];
foreach($ar as $ind=>$rec){
if(!isset($res[$m][$rec['id']])){
$res[$m][$rec['id']] = $rec;
} else {
$res[$m][$rec['id']]['monthly_rental'] += $rec['monthly_rental'];
$res[$m][$rec['id']]['arc'] += $rec['arc'];
}
}
$res[$m] = array_values($res[$m]);
}
return $res;
}
Demo2

How to delete keys from multi-dimension array dynamically

I have to filter this array to see only future items.
How do I unset items from which the timeEnd has expired?
i.e when I call this array at 17:00 there's only array[2] left.
Array
(
[0] => Array
(
[id] => 3034
[date] => 28-09-2016
[timeStart] => 08:30
[timeEnd] => 09:30
[description] => User_A
[locationId] => 1
[roomId] => 8
[relationId] => 104
)
[1] => Array
(
[id] => 2524
[date] => 28-09-2016
[timeStart] => 08:30
[timeEnd] => 12:00
[description] => User_B
[locationId] => 1
[roomId] => 5
[relationId] => 86
)
[2] => Array
(
[id] => 2533
[date] => 28-09-2016
[timeStart] => 09:00
[timeEnd] => 18:00
[description] => User_C
[locationId] => 1
[roomId] => 4
[relationId] => 31
)
)
foreach ($reservations as $key=>$reservation) {
$expireDate = $reservation['date'].' '.$reservation['timeEnd'];
if (strtotime($expireDate) <= strtotime('now')){
unset($reservations[$key]);
}
}

Create a new array having Sum of the same key and values of Array in PHP

Result from Database
(
[ID] => 3167
[dataID] => 1
[data] => P01273
[hours] => 1
[month] => 1
)
(
[ID] => 3168
[dataID] => 1
[data] => P01273
[hours] => 1
[month] => 2
)
(
[ID] => 3191
[dataID] => 2
[data] => P01273
[hours] => 10
[month] => 1
)
(
[ID] => 3196
[dataID] => 2
[data] => P01273
[hours] => 10
[month] => 2
)
(
[ID] => 3189
[dataID] => 2
[data] => P00428
[hours] => 22
[month] => 2
)
(
[ID] => 3189
[dataID] => 2
[data] => P004299
[hours] => 22
[month] => 2
)
if month and data are equal then calculate the SUM of hours
Need Output
(
[ID] => 3167
[dataID] => 1
[data] => P01273
[hours] => 11 (adding 1+11)
[month] => 1
)
(
[ID] => 3168
[dataID] => 1
[data] => P01273
[hours] => 11 (adding 1+11)
[month] => 2
)
(
[ID] => 3189
[dataID] => 2
[data] => P00428
[hours] => 22
[month] => 2
)
(
[ID] => 3189
[dataID] => 2
[data] => P004299
[hours] => 22
[month] => 2
)
That's the main idea. Haven't executed the script so you will have to do the bug fixes if any. Cheers.
$newarray = array(); // global
while($row = mysql_fetch_assoc($result)){
if($idx = isdatasame($row)){
$newarray[$idx]['hour'] += $row['hour']; // add hour to existing record
}
else{
$newarray[] = $row; // if record not in $newarray add new record
}
}
function isdatasame($row){
global $newarray;
for($i=0; $i<COUNT($newarray); $i++){
if($newarray[$i]['data']==$row['data'] && $newarray[$i]['month']==$row['month'] )
return $i;
}
return false;
}

Categories