Array value sum by key value php - php

How can I check columnar values by associative key?
I want to check data by "building_id" . Here I have 2 buildings
then I want rent data as sum with group by "tenancy_rate"
Input array :
Array
(
[0] => Array
(
[id] => 34
[building_id] => 786
[tenancy_rate] => 0
[rent_per_room] => 10000
[management_fee_per_room] => 0
)
[1] => Array
(
[id] => 35
[building_id] => 786
[tenancy_rate] => 10
[rent_per_room] => 11810
[management_fee_per_room] => 5400
[rent] => 86050
)
[2] => Array
(
[id] => 36
[building_id] => 786
[tenancy_rate] => 20
[rent_per_room] => 11810
[management_fee_per_room] => 5400
[rent] => 86050
)
[3] => Array
(
[id] => 56
[building_id] => 798
[tenancy_rate] => 0
[rent_per_room] => 10000
[management_fee_per_room] => 5400
[rent] => 77000
)
[4] => Array
(
[id] => 57
[building_id] => 798
[tenancy_rate] => 10
[rent_per_room] => 11810
[management_fee_per_room] => 5400
[rent] => 86050
)
[5] => Array
(
[id] => 58
[building_id] => 798
[tenancy_rate] => 20
[rent_per_room] => 11810
[management_fee_per_room] => 5400
[rent] => 86050
)
)
Desired result :
Array
(
[0] => Array
(
[tenancy_rate] => 0
[rent] => 77000
)
[1] => Array
(
[tenancy_rate] => 10
[rent] => 172100
)
[2] => Array
(
[tenancy_rate] => 20
[rent] => 172100
)
)
For this I tried PHP code
But not getting any solution
$sumArray = array();
foreach ($myArray as $k=>$subArray) {
foreach ($subArray as $id=>$value) {
$sumArray[$id]+=$value;
}
}
print_r($sumArray);

Here is the snippet. To get the desired result you need to group by tenancy_rate and not by building id,
$result = [];
foreach ($arr as $val) {
// as I see, rent for some array not there, so setting it to 0
$val['rent'] = ($val['rent'] ?? 0);
if (isset($result[$val['tenancy_rate']]['rent'])) {
$result[$val['tenancy_rate']]['rent'] += $val['rent'];
} else {
$result[$val['tenancy_rate']] = [
'tenancy_rate' => $val['tenancy_rate'], 'rent' => $val['rent']];
}
}
print_r($result);
Demo
Output:-
Array
(
[0] => Array
(
[tenancy_rate] => 0
[rent] => 77000
)
[1] => Array
(
[tenancy_rate] => 10
[rent] => 172100
)
[2] => Array
(
[tenancy_rate] => 20
[rent] => 172100
)
)

You can use foreach and group by index tenancy_rate
$f = [];
foreach($a as $v){
if(!empty($f[$v['tenancy_rate']])){
$f[$v['tenancy_rate']]['rent'] += $v['rent'];
}else{
$f[$v['tenancy_rate']] = [
'tenancy_rate' => $v['tenancy_rate'],
'rent' => isset($v['rent']) ? $v['rent'] : 0
];
}
}
Working example :- https://3v4l.org/nWRGA
You can use array_values to re arrange the order of array

At first you need to use calculate rent sum for each tenancy rate:
$rentSums = [];
foreach ($input as $info) {
$tenancyRate = $info['tenancy_rate'] ?? 0;
$rent = $info['rent'] ?? 0;
$rentSum = $rentSums[$tenancyRate] ?? 0;
$rentSums[$tenancyRate] = $rentSum + $rent;
}
Then you can build the result using the data from previous step:
$result = [];
foreach ($rentSums as $tenancyRate => $rentSum) {
$result[] = [
'tenancy_rate' => $tenancyRate,
'rent' => $rentSum,
];
}

Using a function to return the necessary values (rate and rent), and accumulating the values into the sumArray array, making the assumption that the results array keys are related to the tenancy_rate (this allows for insertion of further tenancy_rates).
$sumArray = [];
function processBuildingInfo($building)
{
return [ $building['tenancy_rate']??0, $building['rent']??0 ];
}
foreach ($myArray as $k=>$subArray) {
list($rate, $rent) = processBuildingInfo($subArray);
$sumArray[$rate/10] = [
'tenancy_rate' => $rate,
'rent' => $sumArray[$rate/10]['rent'] + $rent
];
}
print_r($sumArray);

use this loop:
foreach ($myArray as $k=>$subArray) {
foreach ($subArray as $id=>$valueArray) {
$sumArray[$id]+=[
'tenancy_rate' => $valueArray['tenancy_rate'],
'rent' => $valueArray['rent']
];
}
}

Related

How to merge array and sum up the values depending on key?

I have an array something like below. I want to merge the nested array and display the totals. Here ID = 60.I want to merge this [0] and [1] depending in the ID value i.e., 60.
Array(
[0] => Array
(
[ID] => 60
[TOTAL] => 500
)
[1] => Array
(
[ID] => 60
[TOTAL] => 600
)
[2] => Array
(
[ID] => 61
[TOTAL] => 600
)
)
I tried with two for loops
foreach($result as $key=>$value){
foreach($result as $key1 => $value1){
// Do stuffs here
}
}
I want the output as
Array(
[0] => Array(
[ID] =>60
[TOTAL] => 1100
)
[1] =>Array(
[ID] =>61
[TOTAL] => 600
)
)
<?php
$result = Array(
Array
(
'ID' => 60,
'TOTAL' => 500
),
Array
(
'ID' => 60,
'TOTAL' => 600
),
Array
(
'ID' => 61,
'TOTAL' => 600
)
);
$set = [];
foreach($result as $data){
if(!isset($set[$data['ID']])) $set[$data['ID']] = 0;
$set[$data['ID']] += $data['TOTAL'];
}
$result_set = [];
foreach($set as $id => $total){
$result_set[] = [
'ID' => $id,
'TOTAL' => $total
];
}
print_r($result_set);
Demo: https://3v4l.org/NMmHC
We store IDs as keys in our $set array and keep adding the total to it whenever we come across the same key in the foreach loop.
In the end, we collect the results in a new array with ID and it's respective total.
My suggestion is to use array_reduce() which iteratively reduce the array to a single value using a callback function.
$arr = [['ID' => 60,'TOTAL' => 500],['ID' => 60,'TOTAL' => 600],['ID' => 61,'TOTAL' => 600]];
$arr = array_reduce($arr, function($acc, $new) {
if (!isset($acc[$new['ID']])) {
$acc[$new['ID']] = $new;
return $acc;
}
$acc[$new['ID']]['TOTAL'] += $new['TOTAL'];
return $acc;
}, []);
echo '<pre>', print_r(array_values($arr));
Working demo.
Solution 1
$arrayvariable=Array(
[0] => Array
(
[ID] => 60
[TOTAL] => 500
)
[1] => Array
(
[ID] => 60
[TOTAL] => 600
)
[2] => Array
(
[ID] => 61
[TOTAL] => 600
)
)
$output = array_reduce($arrayvariable, function (array $compare, array $item) {
$intrestkey = $item ['ID'];
if (array_key_exists($intrestkey, $compare)) {
$compare [$intrestkey] ['TOTAL'] += $item ['TOTAL'];
} else {
$compare [$intrestkey] = $item;
}
return $compare;
}, array());
$incremetedmerged_array = array_values($output);
print_r($incremetedmerged_array); //Produces
Array(
[0] => Array(
[ID] =>60
[TOTAL] => 1100
)
[1] =>Array(
[ID] =>61
[TOTAL] => 600
)
)

Group subsets of data in 3-level array by identifying column

I've this type of array in PHP:
Array(
[100] => Array(
[1] => Array (
[AVA_Date] => 2019-04-18
[ROO_Id] => 100
[RAT_Id] => 9
)
[2] => Array (
[AVA_Date] => 2019-04-20
[ROO_Id] => 100
[RAT_Id] => 10
)
[4] => Array (
[AVA_Date] => 2019-04-21
[ROO_Id] => 100
[RAT_Id] => 10
)
[7] => Array (
[AVA_Date] => 2019-04-22
[ROO_Id] => 100
[RAT_Id] => 9
)
)
)
I would like to merge items on ROO_Id and RAT_Id.
Then, for the AVA_Date, I need to list them under a new array in the current array.
So, the desired output is:
Array(
[100] => Array(
[0] => Array (
[AVA_Date] => Array (
[0] => 2019-04-18
[1] => 2019-04-22
)
[ROO_Id] => 100
[RAT_Id] => 9
)
[1] => Array (
[AVA_Date] => Array (
[0] => 2019-04-20
[1] => 2019-04-21
)
[ROO_Id] => 100
[RAT_Id] => 10
)
)
)
Here what I have tried:
$newArrOtherRooms = array_reduce($newArr, function($acc, $val) {
$room = array_search($val['ROO_Id'], array_column($acc, 'ROO_Id'));
$rate = array_search($val['RAT_Id'], array_column($acc, 'RAT_Id'));
if($rate == $room && $room > -1) {
array_push($acc[$room]['AVA_Date'], $val['AVA_Date']);
}
else {
$new_arr = $val;
$new_arr['AVA_Date'] = [$val['AVA_Date']];
array_push($acc, $new_arr);
}
return $acc;
},[]);
But it doesn't work like I want.
There are a couple of issues with your code. Firstly, you need to wrap the array_reduce with a foreach over the outer level of $newArr. Secondly, your call to array_search doesn't consider the fact that a ROO_Id or RAT_Id value might exist more than once in the array, as it only returns the first key at which it finds the value. To work around this, you can use array_keys to get an array of key values for each ROO_Id and RAT_Id value, and then take the intersection of those two arrays using array_intersect to see if both are present in the same element. If so, you update that element, otherwise you create a new one:
foreach ($newArr as $key => $array) {
$newArrOtherRooms[$key] = array_reduce($array, function($acc, $val) {
$room = array_keys(array_column($acc, 'ROO_Id'), $val['ROO_Id']);
$rate = array_keys(array_column($acc, 'RAT_Id'), $val['RAT_Id']);
$common = array_intersect($room, $rate);
if(!empty($common)) {
array_push($acc[current($common)]['AVA_Date'], $val['AVA_Date']);
}
else {
$new_arr = $val;
$new_arr['AVA_Date'] = [$val['AVA_Date']];
array_push($acc, $new_arr);
}
return $acc;
},[]);
}
print_r($newArrOtherRooms);
Output:
Array(
[100] => Array(
[0] => Array (
[AVA_Date] => Array (
[0] => 2019-04-18
[1] => 2019-04-22
)
[ROO_Id] => 100
[RAT_Id] => 9
)
[1] => Array (
[AVA_Date] => Array (
[0] => 2019-04-20
[1] => 2019-04-21
)
[ROO_Id] => 100
[RAT_Id] => 10
)
)
)
Demo on 3v4l.org
There is absolutely no reason to be making all of those iterated function calls.
Use a nested loop to iterate the subset of data for each room, group on the room "rate id", and push all "available date" values into a subarray in the respective group. When the subset of data is fully iterated, push its grouped data into the result array.
Code: (Demo)
$result = [];
foreach ($newArr as $rooId => $rows) {
$groups = [];
foreach ($rows as $row) {
if (!isset($groups[$row['RAT_Id']])) {
$row['AVA_Date'] = (array) $row['AVA_Date'];
$groups[$row['RAT_Id']] = $row;
} else {
$groups[$row['RAT_Id']]['AVA_Date'][] = $row['AVA_Date'];
}
}
$result[$rooId] = array_values($groups);
}
var_export($result);
Output:
array (
100 =>
array (
0 =>
array (
'AVA_Date' =>
array (
0 => '2019-04-18',
1 => '2019-04-22',
),
'ROO_Id' => 100,
'RAT_Id' => 9,
),
1 =>
array (
'AVA_Date' =>
array (
0 => '2019-04-20',
1 => '2019-04-21',
),
'ROO_Id' => 100,
'RAT_Id' => 10,
),
),
)

How to prepare a new array out of two arrays inside foreach loop?

I am trying to compare the keys of an array with values of another array. In case of greater values of the current key, I would like to push the value into a new array. Then I want to insert all the collected values for that specific key into a DB table.
These are my input arrays:
$productlist = [result] => Array
(
[0] => Array
(
[configoption1] => 2M
[id] => 96
)
[1] => Array
(
[configoption1] => 5M
[id] => 97
)
[2] => Array
(
[configoption1] => 15M
[id] => 98
)
[3] => Array
(
[configoption1] => 30M
[id] => 99
)
)
$myplans = Array
(
[2M] => Array
(
[price] => 10
)
[5M] => Array
(
[price] => 10
)
[15M] => Array
(
[price] => 10
)
[30M] => Array
(
[price] => 10
)
)
The following is my sample code:
$upgradelist = array()
foreach ($myplans as $plan => $data) {
foreach($productlist['result'] as $key=>$value){
if($plan == 'ENTERPRISE'){
//no higher plans than Enterprise
}else{
$plan1 = (int)substr_replace($plan, "", -1);
$value['configoption1'] = (int)substr_replace($value['configoption1'], "", -1);
#echo " configconfig=> ".$value['configoption1'];
if($plan > $value['configoption1']){
$upgrade_product_ids[$plan][] = $value['id'];
}
}
}
//insert upgrade products list
if(!empty($upgradelist)){
foreach($upgradelist as $key => $upgrade_product_id){
#$insert_stmt_upgradeproduct = <insert statement> for each $plan
}
}
}
expected output each time I come out from the foreach loop: > foreach($productlist['result']
$upgradelist = Array
(
[2] => Array
(
[0] => 97 //5M
[1] => 98 //15M
[2] => 99 //30M
)
)
$upgradelist = Array
(
[5] => Array
(
[0] => 98
[1] => 99
)
)
$upgradelist = Array
(
[15] => Array
(
[0] => 99
)
)
$upgradelist = Array
(
[30] => Array
(
)
)
You can solve like below:
foreach($myplans as $key => $plan) {
$data_to_be_inserted = [];
foreach($productlist['result'] as $product) {
if ($key > $product['configoption1']) {
$data_to_be_inserted [] = $product['id'];
}
}
if (count($data_to_be_inserted)) {
//insert into database(expected value will be available here)
}
}
YOu can do like this
<?php
$myArray = [];
$myArray['result'] = array(
array("configoption1" => "2m", "id" => 96),
array("configoption1" => "5m", "id" => 97),
array("configoption1" => "15m", "id" => 98),
array("configoption1" => "30m", "id" => 99)
);
//print_r($myArray);
$myArray2 =[
"2m" => ["price" => 10],
"5m" => ["price" => 10],
"15m" => ["price" => 10],
"30m" => ["price" => 10]
];
$resultArray = [];
foreach($myArray2 as $key => $values) {
$keyNum = (int)$key;
$newTempArray[$keyNum] = [];
foreach($myArray['result'] as $newresult) {
$configoption1Num = (int)$newresult['configoption1'];
if($configoption1Num > $keyNum) {
array_push($newTempArray[$keyNum], $newresult['id']);
}
}
print_r($newTempArray[$keyNum]);
echo "<br>";
}
http://sandbox.onlinephpfunctions.com/code/008c839fb4fad4ed2aceae7c4ed1220579e8e318

Group data from two 2d arrays by three columns and retaining the lowest value in another column within each group

I have 2 multidimensional Arrays with Flightdates (Price, Date, Airline,..). I want to merge and remove duplicates that have the same date but I need to keep the cheaper one. I have always the same flight, but different prices.
$array1 = array(
[0] => Array
(
[price] => 191
[date1] => 22-07-2016
[date2] => 30-07-2016
[airline] => Lufthansa
)
[1] => Array
(
[price] => 80
[date1] => 25-07-2016
[date2] => 30-07-2016
[airline] => Easyjet
)
[2] => Array
(
[price] => 243
[date1] => 10-08-2016
[date2] => 36-08-2016
[airline] => Airberlin
)
);
$array2 = array(
[0] => Array
(
[price] => 230
[date1] => 22-07-2016
[date2] => 30-07-2016
[airline] => Lufthansa
)
[1] => Array
(
[price] => 80
[date1] => 25-07-2016
[date2] => 30-07-2016
[airline] => Easyjet
)
[2] => Array
(
[price] => 200
[date1] => 10-08-2016
[date2] => 36-08-2016
[airline] => Airberlin
)
);
Just loop through the first array and match the price in second array with respect to key of first array and push the values into into new array..
First Answer
<?php
$newArray = array();
foreach($array1 as $key =>$val)
{
if($val['price'] <= $array2[$key]['price'])
{
$newArray[] = $val;
}
else
{
$newArray[] = $array2[$key];
}
}
print_r($newArray);
?>
LIVE EXAMPLE : CLICK HERE
Second Answer
$newArray = array();
foreach($array1 as $key => $val)
{
foreach($array2 as $k => $v)
{
if($val['date1'] == $v['date1'] && $val['date2'] == $v['date2'] && $val['airline'] == $v['airline'])
{
if($val['price'] <= $array2[$key]['price'])
{
$newArray[] = $val;
}
else
{
$newArray[] = $v;
}
}
}
}
print_r($newArray);
LIVE EXAMPLE : CLICK HERE
This will give you :
Array
(
[0] => Array
(
[price] => 191
[date1] => 22-07-2016
[date2] => 30-07-2016
[airline] => Lufthansa
)
[1] => Array
(
[price] => 80
[date1] => 22-07-2016
[date2] => 30-07-2016
[airline] => Easyjet
)
[2] => Array
(
[price] => 200
[date1] => 22-07-2016
[date2] => 30-07-2016
[airline] => Airberlin
)
)

How to transpose array elements? [duplicate]

This question already has answers here:
Transposing multidimensional arrays in PHP
(12 answers)
Closed 11 months ago.
I have an array $categories in php as follows.
Array
(
[item_name] => Array
(
[0] => I-Phone
[1] => samsung
[2] => nokia
[3] => htc
)
[item_price] => Array
(
[0] => 30.00
[1] => 20
[2] => 10
[3] => 15
)
)
And I want to transpose its element as,
Array
(
[0] => Array
(
[item_name] => I-Phone
[item_price] => 30.00
)
[1] => Array
(
[item_name] => samsung
[item_price] => 20
)
[2] => Array
(
[item_name] => nokia
[item_price] => 10
)
[2] => Array
(
[item_name] => htc
[item_price] => 15
)
)
I've tried using foreach loop but not working.
$count=0;
foreach ($categories as $key=> $category)
{
$categories[$count] = $category[$key];
$categories[$count] = $category[$key];
$count++;
}
Here's an approach:
$categories = array(
'item_name' => array('I-Phone', 'samsung', 'nokia','htc'),
'item_price' => array('30.00', '20', '10', '15')
);
$out = array();
foreach($categories as $key => $a){
foreach($a as $k => $v){
$out[$k][$key] = $v;
}
}
echo '<pre>';
print_r($out);
echo '</pre>';
Simple solution using array_keys and array_map functions:
$keys = array_keys($categories);
$transposed = array_map(function($a, $b) use($keys){
return [$keys[0] => $a, $keys[1] => $b];
}, $categories['item_name'], $categories['item_price']);
print_r($transposed);
The output:
Array
(
[0] => Array
(
[item_name] => I-Phone
[item_price] => 30
)
[1] => Array
(
[item_name] => samsung
[item_price] => 20
)
[2] => Array
(
[item_name] => nokia
[item_price] => 10
)
[3] => Array
(
[item_name] => htc
[item_price] => 15
)
)
Something like this:
$categories = array(); // your array
$ctg_names = array_keys($categories); // get names of source array keys
$new_ctgs = array(); // result array
// iterate over first key values to get indexes
foreach ($categories[$ctg_names[0]] as $k => $v) {
$ctg = array();
// iterate over all key names
foreach ($ctg_names as $name) {
$ctg[$name] = $categories[$name][$k];
}
$new_ctgs[] = $ctg;
}
print_r($new_ctgs);
Try this:
<?php
$array = Array
(
'item_name' => Array
(
'0' => 'I-Phone',
'1' => 'samsung',
'2' => 'nokia',
'3' => 'htc',
),
'item_price' => Array
(
'0' => 30.00,
'1' => 20,
'2' => 10,
'3' => 15,
)
);
$keys = array_keys($array);
$result = array();
for($i = 0; $i < count($array['item_name']); $i++)
{
$tempArray = array();
foreach($keys as $key)
$tempArray[$key] = $array[$key][$i];
$result[] = $tempArray;
}
Output:
Array
(
[0] => Array
(
[item_name] => I-Phone
[item_price] => 30
)
[1] => Array
(
[item_name] => samsung
[item_price] => 20
)
[2] => Array
(
[item_name] => nokia
[item_price] => 10
)
[3] => Array
(
[item_name] => htc
[item_price] => 15
)
)
$result = [];
foreach($categories['Item_name'] as $key => $data){
$result[$key]['category'] = $categories['Item_name']['$key'];
$result[$key]['price'] = $categories['price'][$key];
}
dd($result);

Categories