This is my two multidimensional array and i want get unique value and when same iProduct_id's value is occured then subtraction of fTotal_qty. I need help. Thank you in Advance.
This is Array1
Array(
[0] => Array
(
[iProduct_id] => 1
[fTotal_qty] => 200
)
[1] => Array
(
[iProduct_id] => 4
[fTotal_qty] => 100
)
)
This is Array2
Array
(
[0] => Array
(
[iProduct_id] => 1
[fTotal_qty] => 500
)
[1] => Array
(
[iProduct_id] => 2
[fTotal_qty] => 400
)
[2] => Array
(
[iProduct_id] => 6
[fTotal_qty] => 700
)
[3] => Array
(
[iProduct_id] => 4
[fTotal_qty] => 300
)
[4] => Array
(
[iProduct_id] => 5
[fTotal_qty] => 200
)
)
And i want like this output
iProduct_id = 1, fTotal_qty = 300
iProduct_id = 2, fTotal_qty = 400
iProduct_id = 6, fTotal_qty = 700
iProduct_id = 4, fTotal_qty = 200
You need to use array_map() function in php
array_map(myfunction,array1,array2,array3...)
Here myfunction is the way which will contain logic to do substraction and merging of your items.
array1 , array2 ,array3 are the number of array which may contain your data.
You can do the following:
foreach($array1 as $index => $value) {
$key = array_search($value['iProduct_id'], $array2);
if($key) {
$newArray[$index]['iProduct_id'] = $value['iProduct_id'];
$newArray[$index]['fTotal_qty'] = $array2[$key]['fTotal_qty'] - $value['fTotal_qty'];
}
}
$finalArray = array_diff($array2,$newArray);
var_dump(array_merge($finalArray,$newArray));
I hope it would be helpful.
<?php
$one =
[
[
'id'=>1,
'amount' => 100
],
[
'id'=>2,
'amount' => 200
],
];
$two =
[
[
'id'=>1,
'amount' => 700
],
[
'id'=>2,
'amount' => 800
],
[
'id'=>3,
'amount' => 900
],
];
$one_id_amount = array_column($one, 'amount', 'id');
foreach($result = $two as $k => $v)
$result[$k]['amount'] -= $one_id_amount[$v['id']] ?? 0;
var_export($result);
Output:
array (
0 =>
array (
'id' => 1,
'amount' => 600,
),
1 =>
array (
'id' => 2,
'amount' => 600,
),
2 =>
array (
'id' => 3,
'amount' => 900,
),
)
<?php
$arr1 = array(
array('iProduct_id' => 4,'fTotal_qty' => 100),
array('iProduct_id' => 2,'fTotal_qty' => 100)
);
$arr2 = array(
array('iProduct_id' => 1,'fTotal_qty' => 500),
array('iProduct_id' => 2,'fTotal_qty' => 450),
array('iProduct_id' => 6,'fTotal_qty' => 700),
array('iProduct_id' => 4,'fTotal_qty' => 300),
array('iProduct_id' => 5,'fTotal_qty' => 200)
);
echo "<pre>";
echo "array1 = "; print_r($arr1);
echo "array2 = "; print_r($arr2);
$key = array_column($arr1, 'iProduct_id');
$arraySub = array();
$sub = array();
for ($i=0; $i < count($arr2); $i++) {
if (array_search($arr2[$i]['iProduct_id'],$key) != '' || array_search($arr2[$i]['iProduct_id'],$key) == 0)
{
$arraySub['val1'] = array_search($arr2[$i]['iProduct_id'],$key);
$arraySub['val2'] = $i;
}
$sub[] = $arraySub;
}
foreach ($sub as $value) {
if ($arr1[$value['val1']]['iProduct_id'] != '' && $arr2[$value['val2']]['iProduct_id'] != '') {
if ($arr1[$value['val1']]['iProduct_id'] == $arr2[$value['val2']]['iProduct_id'] ) {
$arr2[$value['val2']]['fTotal_qty'] = abs($arr2[$value['val2']]['fTotal_qty']) - abs($arr1[$value['val1']]['fTotal_qty']);
}
}
}
echo "(array1 - array2) = "; print_r($arr2); // your subtrected value has been stored in arr2
?>
Tested answer:
<?php
$Array1 =
[
[
'iProduct_id'=>1,
'fTotal_qty' => 200
],
[
'iProduct_id'=>4,
'fTotal_qty' => 100
],
];
$Array2 =
[
[
'iProduct_id'=>1,
'fTotal_qty' => 500
],
[
'iProduct_id'=>2,
'fTotal_qty' => 400
],
[
'iProduct_id'=>6,
'fTotal_qty' => 700
],
[
'iProduct_id'=>4,
'fTotal_qty' => 300
],
[
'iProduct_id'=>5,
'fTotal_qty' => 200
],
];
$one_id_amount = array_column($Array1, 'fTotal_qty', 'iProduct_id');
foreach($result = $Array2 as $k => $v)
$result[$k]['fTotal_qty'] -= $one_id_amount[$v['iProduct_id']] ?? 0;
foreach ($result as $line) {
echo "iProduct_id =" . $line['iProduct_id'] . ", fTotal_qty = " . $line['fTotal_qty'] . "<br>";
}
I hope it would be helpful.
Related
I will try to explain my problem in small examples:
I have a multidimensional array that represents data from the database, lets's say the input looks like this:
Array
(
[0] => Array
(
[groupRange] => 20-25
[value] => 12
[followersFemaleRate] => 12
[followersMaleRate] => 14
)
[1] => Array
(
[groupRange] => 30-44
[value] => 32
[followersFemaleRate] => 17
[followersMaleRate] => 3
)
[2] => Array
(
[groupRange] => 30-44
[value] => 88
[followersFemaleRate] => 17
[followersMaleRate] => 3
)
)
What I want? To sum value, followersFemaleRate, followersMaleRate with the same groupRange, so the output should be this:
Array
(
[0] => Array
(
[groupRange] => 20-25
[value] => 12
[followersFemaleRate] => 12
[followersMaleRate] => 14
)
[1] => Array
(
[groupRange] => 30-44
[value] => 120
[followersFemaleRate] => 34
[followersMaleRate] => 6
)
)
My code:
$RangeArray = [];
foreach($dbProfile->getData() as $d) {
foreach ($d->getGroupPercentages() as $x){
$ageRangeSingleArray['groupRange'] = $x->getGroupRange();
$ageRangeSingleArray['value'] = $x->getValue();
$ageRangeSingleArray['followersFemaleRate'] = $x->getFollowerGenderFemale();
$ageRangeSingleArray['followersMaleRate'] = $x->getFollowerGenderMale();
$RangeArray [] = $ageRangeSingleArray;
}
}
However im stuck, my idea is to first check if groupRage already exists, if yes, sum values for that range, if not add new element groupRange with values, any help with code?
#Salines solution was good, but I offer a simple solution for the beginners...
Another simple solution to your problem:
$input = [
[
'groupRange' => '20-25',
'value' => 12,
'followersFemaleRate' => 12,
'followersMaleRate' => 14,
],
[
'groupRange' => '30-44',
'value' => 88,
'followersFemaleRate' => 17,
'followersMaleRate' => 3,
],
[
'groupRange' => '30-44',
'value' => 32,
'followersFemaleRate' => 17,
'followersMaleRate' => 3,
],
];
$groupRangeHolder = [];
$output = [];
foreach($input as $item) {
if( ! array_key_exists( $item['groupRange'] , $groupRangeHolder ) )
{
$groupRangeHolder[$item['groupRange']]['value'] = $item['value'];
$groupRangeHolder[$item['groupRange']]['followersFemaleRate'] = $item['followersFemaleRate'];
$groupRangeHolder[$item['groupRange']]['followersMaleRate'] = $item['followersMaleRate'];
}
else
{
$groupRangeHolder[$item['groupRange']]['value'] += $item['value'];
$groupRangeHolder[$item['groupRange']]['followersFemaleRate'] += $item['followersFemaleRate'];
$groupRangeHolder[$item['groupRange']]['followersMaleRate'] += $item['followersMaleRate'];
}
}
$cur = 0;
foreach($groupRangeHolder as $key => $values)
{
$output[$cur]['groupRange'] = $key;
$output[$cur]['value'] = $values['value'];
$output[$cur]['followersFemaleRate'] = $values['followersFemaleRate'];
$output[$cur++]['followersMaleRate'] = $values['followersMaleRate'];
}
echo "<pre>";
print_r($output);
echo "</pre>";
try:
$input = [
[
'groupRange' => '20-25',
'value' => 12,
'followersFemaleRate' => 12,
'followersMaleRate' => 14,
],
[
'groupRange' => '30-44',
'value' => 88,
'followersFemaleRate' => 17,
'followersMaleRate' => 3,
],
[
'groupRange' => '30-44',
'value' => 32,
'followersFemaleRate' => 17,
'followersMaleRate' => 3,
],
];
$groupedArray = [];
foreach( $input as $item ){
$groupedArray[$item['groupRange']]['groupRange'] = $item['groupRange'];
$groupedArray[$item['groupRange']]['value'] = ($groupedArray[$item['groupRange']]['value'] ?? 0) + $item['value'];
$groupedArray[$item['groupRange']]['followersFemaleRate'] = $item['followersFemaleRate'];
$groupedArray[$item['groupRange']]['followersMaleRate'] = $item['followersMaleRate'];
}
$output = array_values($groupedArray);
print_r($output);
output:
Array
(
[0] => Array
(
[groupRange] => 20-25
[value] => 12
[followersFemaleRate] => 12
[followersMaleRate] => 14
)
[1] => Array
(
[groupRange] => 30-44
[value] => 120
[followersFemaleRate] => 17
[followersMaleRate] => 3
)
)
I have a PHP array that looks like this...
$array = [
'item1' => [
[
'productCount' => '3',
'value' => 'red',
],
[
'productCount' => '3',
'value' => 'green',
],
[
'productCount' => '3',
'value' => 'green',
]
],
'item2' => [
[
'productCount' => '1',
'value' => 'purple',
]
],
];
I am trying to parse it so it looks like this...
Array
(
[item1] => Array
(
[productCount] => 3
[red] => 1
[green] => 2
)
[item1] => Array
(
[productCount] => 1
[purple] => 1
)
)
I have this so far....
$finalArray = array();
foreach ($array as $key => $arrayItem) {
$finalArray[$key] = $arrayItem['productCount'];
$valueCount = count($arrayItem['productCount']);
$finalArray[$key] = $valueCount;
}
I know this isn't much but I am stuck at this point. How do I process the values and count them in the new array?
This code will give you the results you want. It loops over the upper level array to get the keys and productCount values for the new array. Then it loops over the second level arrays to get the counts of each value:
$output = array();
foreach ($array as $key => $items) {
$output[$key] = array('productCount' => $items[0]['productCount']);
foreach ($items as $item) {
$value = $item['value'];
$output[$key][$value] = ($output[$key][$value] ?? 0) + 1;
}
}
print_r($output);
The inner loop can be written more concisely using array_column and array_count_values:
$output = array();
foreach ($array as $key => $items) {
$output[$key] = array_merge(array('productCount' => $items[0]['productCount']),
array_count_values(array_column($items, 'value')));
}
print_r($output);
In both cases the output is:
Array
(
[item1] => Array
(
[productCount] => 3
[red] => 1
[green] => 2
)
[item2] => Array
(
[productCount] => 1
[purple] => 1
)
)
Demo on 3v4l.org
For dynamic get all result use two times foreach loops
$array = [
'item1' => [
[
'productCount' => '3',
'value' => 'red',
],
[
'productCount' => '3',
'value' => 'green',
],
[
'productCount' => '3',
'value' => 'green',
]
],
'item2' => [
[
'productCount' => '1',
'value' => 'purple',
]
],
];
$new_array = $final_array = array();
foreach ($array as $key => $arrayItem) {
foreach($arrayItem as $sub_key=>$second_item){
$new_array[$key]['productCount'] = $second_item['productCount'];
$new_array[$key][$second_item['value']][] =$second_item['value'];
}
}
foreach ($new_array as $key => $value) {
foreach($value as $sub_key =>$sub_value){
$final_array[$key][$sub_key] = (is_array($sub_value))?count($sub_value):$sub_value;
}
}
print_r($final_array);exit;
Output
Array
(
[item1] => Array
(
[productCount] => 3
[red] => 1
[green] => 2
)
[item2] => Array
(
[productCount] => 1
[purple] => 1
)
)
Hope this is helpful to you.
I have 2 arrays of arrays which I want to merge by keys for the first step and them sum on the second step - example:
Array
(
[2017-03-01] => Array
(
[apples] => 2
[bananas] => 1
)
[2017-03-02] => Array
(
[apples] => 3
[bananas] => 6
)
[2017-03-03] => Array
(
[apples] => 0
[bananas] => 4
)
}
Array
(
[2017-03-01] => Array
(
[apples] => 3
[bananas] => 2
)
[2017-03-02] => Array
(
[apples] => 4
[bananas] => 7
)
[2017-03-03] => Array
(
[apples] => 1
[bananas] => 5
)
}
Wanted result:
Array
(
[2017-03-01] => Array
(
[apples] => 5
[bananas] => 3
)
[2017-03-02] => Array
(
[apples] => 7
[bananas] => 13
)
[2017-03-03] => Array
(
[apples] => 1
[bananas] => 9
)
}
Is there a command that does that (as a 1 single command) that will avoid looping through the arrays?
No. (obligatory additional characters)
Here's an insanely inefficient way of doing but without using any sort of for foreach or while
$result = array_map(function ($aentry, $key) use ($b) {
$bentry = $b[$key] ?? [];
$result = array_map(function ($value, $key) use ($bentry) {
return [$key, $value + ($bentry[$key] ?? 0) ];
},$aentry, array_keys($aentry));
return [ $key, array_combine(array_column($result, 0), array_column($result, 1)) ];
}, $a,array_keys($a));
$result = array_combine(array_column($result, 0), array_column($result, 1));
Example: http://sandbox.onlinephpfunctions.com/code/4c1dca3057c33dd17d0106666a497c7b08e57038
Solution without for/foreach/... , assuming that all keys are the same, you can do:
$array1 = [
'2017-03-01' => [
'apples' => 2,
'bananas' => 1,
],
'2017-03-02' => [
'apples' => 3,
'bananas' => 6,
],
'2017-03-03' => [
'apples' => 0,
'bananas' => 4,
],
];
$array2 = [
'2017-03-01' => [
'apples' => 3,
'bananas' => 2,
],
'2017-03-02' => [
'apples' => 4,
'bananas' => 7,
],
'2017-03-03' => [
'apples' => 1,
'bananas' => 5,
],
];
array_walk($array1, function(&$subarray1, $key) use($array2) {
array_walk($subarray1, function(&$element, $subkey) use($array2, $key) {
$element += $array2[$key][$subkey];
});
});
Not good performance, just for fun.
Thank you all for your answers, here is my code:
function merge_fruit_data($new_data, $old_data){
// If it's the first time running - return new data as an array
if (empty($old_data)){
return $new_data;
}
else {
foreach ( $new_data as $key => $insert_new_data ) {
if ( !$old_data[$key] ) {
$old_data[$key] = $insert_new_data;
}
else{
$old_data[$key]['apples'] += $insert_new_data['apples'];
$old_data[$key]['bananas'] += $insert_new_data['bananas'];
}
}
}
return $old_data;
}
Efficiency comments are welcome.
This may help you
`$a = array('2017-03-01' => array('apples'=> 2, 'bananas'=>1),
'2017-03-02' => array('apples'=> 3, 'bananas'=>6),
'2017-03-03' => array('apples'=> 0, 'bananas'=>4));
$b=array('2017-03-01' => array('apples'=> 3, 'bananas'=>2),
'2017-03-02' => array('apples'=> 4, 'bananas'=>7),
'2017-03-03' => array('apples'=> 1, 'bananas'=>5));
$sumArray = array();
foreach ($a as $key=>$value) {
$sumArray[$key]['apples']=($a[$key]['apples']+$b[$key]['apples']);
$sumArray[$key]['bananas']=($a[$key]['bananas']+$b[$key]['bananas']);
}
print_r($sumArray);
`
This question already has answers here:
Group multidimensional array data based on two column values and sum values of one column in each group
(5 answers)
Closed 7 months ago.
I have the following array, in which I want to sum up the total_volume for all entries where the source and the target are the same.
Array (
[0] => Array
(
[source] => ABC
[target] => DEF
[total_volume] => 10
)
[1] => Array
(
[source] => ABC
[target] => GHI
[total_volume] => 5
)
[2] => Array
(
[source] => ABC
[target] => DEF
[total_volume] => 5
)
)
The resulting array should look like this:
ResultArray (
[0] => Array
(
[source] => ABC
[target] => DEF
[total_volume] => 15
)
[1] => Array
(
[source] => ABC
[target] => GHI
[total_volume] => 5
)
)
My first thought would be to llop through the existing array and check via a nested loop over the ResultArray whether an entry with the matching source-target-pair already exists.
Is there an other way using array_walk() or a similar method?
Thanks in advance for your help!
not pretty but heres how I would do it with a nested foreach;
$aStartingArray = array();
$aStartingArray[] = array('source'=>'ABC', 'target' => 'DEF', 'total_volume' => 10);
$aStartingArray[] = array('source'=>'ABC', 'target' => 'GHI', 'total_volume' => 5);
$aStartingArray[] = array('source'=>'ABC', 'target' => 'DEF', 'total_volume' => 5);
$aSortedArray = array();
foreach ($aStartingArray as $aArray) {
$bSet = false;
foreach ($aSortedArray as $iPos => $aTempSortedArray) {
if(
$aTempSortedArray['source'] == $aArray['source'] &&
$aTempSortedArray['target'] == $aArray['target']){
$aSortedArray[$iPos]['total_volume'] += $aArray['total_volume'];
$bSet = true;
}
}
if(!$bSet) {
$aSortedArray[] = array(
'source' => $aArray['source'],
'target' => $aArray['target'],
'total_volume' => $aArray['total_volume']
);
}
}
var_dump($aSortedArray);
This is a fast try (sorry, it uses twice array_walk)
<?php
$a = [
['source' => 'ABC', 'target' => 'DEF', 'total_volume' => 10 ],
['source' => 'ABC', 'target' => 'GHI', 'total_volume' => 5 ],
['source' => 'ABC', 'target' => 'DEF', 'total_volume' => 5 ],
];
$tmp = [];
array_walk($a, function (&$item, $key) use (&$tmp) {
$resKey = $item['source'].'_'.$item['target'];
if (!isset($result[$resKey])) {
$result[$resKey] = 0;
}
$tmp[$resKey] += $item['total_volume'];
});
$result = [];
array_walk($tmp, function (&$item, $key) use (&$result) {
list ($source, $target) = explode('_', $key);
$result[] = ['source' => $source, 'target' => $target, 'total_volume' => $item];
});
var_dump($result);
How about this? A bit briefer I think.
$a = [
['source' => 'ABC', 'target' => 'DEF', 'total_volume' => 10 ],
['source' => 'ABC', 'target' => 'GHI', 'total_volume' => 5 ],
['source' => 'ABC', 'target' => 'DEF', 'total_volume' => 5 ],
];
$result = $result2 = [];
array_walk($a, function(&$item, $key) use(&$result) {
if(! isset($result[$item['source']]))
$result[$item['source']] = [];
if(! isset($result[$item['source']][$item['target']]))
$result[$item['source']][$item['target']] = 0;
$result[$item['source']][$item['target']] += $item['total_volume'];
});
foreach($result as $key => $val) {
foreach($val as $k => $v) {
$result2[] = [$key,$k,$v];
}
}
print_r($result2);
Another alternative. Not best but will work.
$arr = [
['source' => 'ABC', 'target' => 'DEF', 'total_volume' => 10 ],
['source' => 'ABC', 'target' => 'GHI', 'total_volume' => 5 ],
['source' => 'ABC', 'target' => 'DEF', 'total_volume' => 5 ],
];
$res = $resulrArr = [];
foreach($arr as $record){
$record = array_values($record);
$res[$record[0].'_'.$record[1]] = !empty($res[$record[0].'_'.$record[1]]) ? $res[$record[0].'_'.$record[1]] + $record[2] : $record[2];
}
$resulrArr = array_map(function($v,$k){
$data = explode('_',$k);
$resulrArr['source'] = $data[0];
$resulrArr['target'] = $data[1];
$resulrArr['total_volume'] = $v;
return $resulrArr;
},$res,array_keys($res));
echo '<pre>'; print_r($resulrArr);
I am new to php and i want to remove element from array Here is my array:
Array
(
[Total] => 21600000
[Items] => Array
(
[2-13] => Array
(
[Item] => 2
[PID] => 13
[UPrice] => 11000000
[Qty] => 1
[Total] => 11000000
)
[58-167] => Array
(
[Item] => 58
[PID] => 167
[UPrice] => 5300000
[Qty] => 1
[Total] => 5300000
)
)
)
And i want to remove array element by PID.
I have try this but no luck:-
$ShoppingBag =$_SESSION['ssss'];
if ($ShoppingBag !== null && $ShoppingBag['Total'] > 0) {
foreach ($ShoppingBag['Items'] as $IOrder) {
if($IOrder["PID"]==13)
{
unset($ShoppingBag[$IOrder]);
}else
{
}
}
}
Please help. Thanks
You can try with one simple array map :)
$arr = [
'Total' => 21600000,
'Items' => [
'2-13' => [
'Item' => 2,
'PID' => 13,
'UPrice' => 11000000,
'Qty' => 1,
'Total' => 11000000
],
'58-167'=> [
'Item' => 58,
'PID' => 167,
'UPrice' => 5300000,
'Qty' => 1,
'Total' => 5300000
]
]
];
$test = array_map(function($ar) {
foreach($ar as $k=>$i) {
if( isset($i['PID']) && $i['PID'] == '13')
unset($ar[$k]);
}
return $ar; } , $arr);
var_dump($test);
You need 2 loop to do the action you want.
foreach($my_array as $key=>$value)
{
if(is_array($value))
{
foreach($value as $k=>$v)
{
if($k == 'PID')
{
unset($value[$k]);
}
}
}
}
with this you can remove only element with key PID.
Hi youre unsetting the $IOrder instead of the Item that you want to delete:
This code is a solution an i tested it :
$ShoppingBag = Array
(
"Total" => 21600000,
"Items" => Array
(
"2-13" => Array
(
"Item" => 2,
"PID" => 13,
"UPrice" => 11000000,
"Qty" => 1,
"Total" => 11000000,
),
"58-167" => Array
(
"Item" => 58,
"PID" => 167,
"UPrice" => 5300000,
"Qty" => 1,
"Total" => 5300000,
),
),
);
foreach($ShoppingBag["Items"] as $key => $value){
if($value["PID"]==13){
unset($ShoppingBag["Items"][$key]);
}
}
You should know that always when you're using foreach loop the foreach( $a as $b ) when you do something to $b , $a remains the same because tey are different variables :)
Hope it will help you .
Regards.
$arr = [
'Total' => 21600000,
'Items' => [
'2-13' => [
'Item' => 2,
'PID' => 13,
'UPrice' => 11000000,
'Qty' => 1,
'Total' => 11000000
],
'58-167'=> [
'Item' => 58,
'PID' => 167,
'UPrice' => 5300000,
'Qty' => 1,
'Total' => 5300000
]
]
];
$pid_to_remove = 13;
$new_ar = array_filter(
$arr,
function ($v) using ($pid_to_remove) {
return (!isset($v['PID'])) || ($v['PID'] != $pid_to_remove);
}
);