I struggle to clean a multidimensional array. I find several Q&A:s on this topic but yet I can't get it to work.
The array $overPayments comes out (from a db call) as below.
Array (
[0] => Array (
[invoiceID] => 103080
[invoiceNumber] => 781
[faktBel] => 1500.00
[totalPayed] => 1500.00
[sumPayedOnThisJournal] => 1500.00
[totOPtoday] => 0.00
[totOPbeforeToday] => -1500.00
[totOPthisJournal] => 0.00 )
[1] => Array(
[invoiceID] => 103290
[invoiceNumber] => 7818
[faktBel] => 648.00
[totalPayed] => 893.00
[sumPayedOnThisJournal] => 893.00
[totOPtoday] => 245.00
[totOPbeforeToday] => -648.00
[totOPthisJournal] => 245.00 )
[2] => Array (
[invoiceID] => 103453
[invoiceNumber] => 202071
[faktBel] => 2250.00
[totalPayed] => 2317.00
[sumPayedOnThisJournal] => 2317.00
[totOPtoday] =>67.00
[totOPbeforeToday] => -2250.00
[totOPthisJournal] => 67.00 )
)
What I need to do is loop through the array called $overPayments containing about 200 sub arrays, and remove all "rows" (subarrays) that have $overPayment['totOPthisJournal'] <= 0. So that I end up with a either modified or new multidimensional array where the totOPthisJournal value is > 0.
I think array_filter is what you are after.
$filteredArray = array_filter($overPayments, function($value) {
return $value['totOPthisJournal'] > 0;
});
just try to unset the array index for which 'totOPthisJournal' is <=0
<?php
$array = Array ( '0' => Array ( 'invoiceID' => 103080, 'invoiceNumber' => 781, 'faktBel' => 1500.00,
'totalPayed' => 1500.00,'sumPayedOnThisJournal' => 1500.00, 'totOPtoday' => 0.00,
'totOPbeforeToday' => -1500.00, 'totOPthisJournal' => 0.00 ), '1' => Array( 'invoiceID' => 103290,
'invoiceNumber' => 7818, 'faktBel' => 648.00, 'totalPayed' => 893.00,
'sumPayedOnThisJournal' => 893.00,'totOPtoday' => 245.00, 'totOPbeforeToday' => -648.00,
'totOPthisJournal' => 245.00 ), '2' => Array ( 'invoiceID' => 103453,'invoiceNumber' => 202071,
'faktBel' => 2250.00, 'totalPayed' => 2317.00, 'sumPayedOnThisJournal' => 2317.00,
'totOPtoday' =>67.00, 'totOPbeforeToday' => -2250.00, 'totOPthisJournal' => 67.00));
foreach($array as $key=>$value){
if($array[$key]['totOPthisJournal'] <= 0){
unset($array[$key]);
}
}
print_r($array);
Put this array into a foreach loop:
foreach($overPayments as $key => $value) {
if($value['totOPthisJournal'] <= 0) {
$key = null;
}
}
This removes the overPayment where [totOPthisJournal] <= 0.
Hope this helps.
Related
I have an array($data) like this.
Array
(
[0] => Array
(
[PID] => 1
[USER_NAME] => JOHN
[JOINED_DATE] => 2022-01-31
[JOINED_VALUE] => 23233.80
[TOPUP_AMOUNT] => 58000.00
[TOTAL_EXPENSES] => 3114.41
)
.....
I need to get a new key called TOTAL_BALANCE and it should get as follows,
TOTAL_BALANCE=JOINED_VALUE+TOPUP_AMOUNT+TOTAL_EXPENSES
Final output should look as follows,
Array
(
[0] => Array
(
[PID] => 1
[USER_NAME] => JOHN
[JOINED_DATE] => 2022-01-31
[JOINED_VALUE] => 23233.80
[TOPUP_AMOUNT] => 58000.00
[TOTAL_EXPENSES] => 3114.41
[TOTAL_BALANCE] => 78119.39
)
.....
Can someone help me to achieve this?
Here is my try, but I am not sure this is correct or not.
$r = [];
$keys = array_keys($key1+$key2);
foreach($keys as $v){
??
}
Do it like this:
$data = Array(
0 => Array(
'PID' => 1,
'USER_NAME' => 'JOHN',
'JOINED_DATE' => '2022-01-31',
'JOINED_VALUE' => 23233.80,
'TOPUP_AMOUNT' => 58000.00,
'TOTAL_EXPENSES' => 3114.41,
),
1 => Array(
'PID' => 2,
'USER_NAME' => 'JOHN_2',
'JOINED_DATE' => '2022-01-31',
'JOINED_VALUE' => 1234.80,
'TOPUP_AMOUNT' => 1000.00,
'TOTAL_EXPENSES' => 3114.41,
)
);
foreach($data as &$value){
// Sum and store
$value['TOTAL_BALANCE'] = $value['JOINED_VALUE'] + $value['TOPUP_AMOUNT'] + $value['TOTAL_EXPENSES'];
}
print_r($data);
Output:
Array
(
[0] => Array
(
[PID] => 1
[USER_NAME] => JOHN
[JOINED_DATE] => 2022-01-31
[JOINED_VALUE] => 23233.8
[TOPUP_AMOUNT] => 58000
[TOTAL_EXPENSES] => 3114.41
[TOTAL_BALANCE] => 84348.21
)
[1] => Array
(
[PID] => 2
[USER_NAME] => JOHN_2
[JOINED_DATE] => 2022-01-31
[JOINED_VALUE] => 1234.8
[TOPUP_AMOUNT] => 1000
[TOTAL_EXPENSES] => 3114.41
[TOTAL_BALANCE] => 5349.21
)
)
Very much new to PHP and completely stuck because of #attributes when trying to pick values out of an array. I have previously converted an xml file into a associative array.
print_r(array_keys($newArray));
Prints:
Array ( [0] => #attributes [1] => rate )
print_r ($newArray);
Prints:
Array (
[#attributes] => Array (
[base] => GBP
[ts] => 1572881347 )
[rate] => Array (
[0] => Array (
[#attributes] => Array (
[code] => AED
[rate] => 4.739532203531
[live] => 0
)
)
[1] => Array (
[#attributes] => Array (
[code] => AFN
[rate] => 100.80144337913
[live] => 0
)
)
[2] => Array (
[#attributes] => Array (
[code] => ALL
[rate] => 142.29721877018
[live] => 0
)
)
[3] => Array (
[#attributes] => Array (
[code] => AMD
[rate] => 614.98298701028
[live] => 0
)
)
How would I specify and print the last value?
[3] => Array ( [#attributes] => Array ( [code] => AMD [rate] => 614.98298701028 [live] => 0.
With the goal to output something like: AMD, 614.98298701028, 0
Thanks
More generally, if you'd want to look-up a currency in your array, you could use following recursive function:
$code = 'AMD'; // set the curncy you want to lookup
forex($code, $newArray); // invoke the recursive function
// output:
//code : AMD
//rate : 614.98298701028
function forex(string $code = '', array $arr = []): void
{
foreach ($arr as $key => $value) {
if (is_array($value) && $key !== '#attributes') {
forex($code, $value);
} else {
if (isset($value['code']) && $value['code'] == $code) {
echo 'code : ' . $value['code'];
echo '<br />';
echo 'rate : ' . $value['rate'];
echo '<br />';
}
}
}
}
working demo
Assuming that your original array is something like this:
$a = array(
'#attributes' => array(
'base' => 'GBP',
'ts' => 1572881347),
'rate' => array(
0 => array(
'#attributes' => array(
'code' => 'AED',
'rate' => 4.739532203531,
'live' => 0,
),
),
1 => array(
'#attributes' => array(
'code' => 'AFN',
'rate' => 100.80144337913,
'live' => 0,
),
),
2 => array(
'#attributes' => array(
'code' => 'ALL',
'rate' => 142.29721877018,
'live' => 0,
),
),
3 => array(
'#attributes' => array(
'code' => 'AMD',
'rate' => 614.98298701028,
'live' => 0,
),
)));
then you can get what you want with this:
$last_rate = sizeof($a['rate']) - 1;
foreach ($a['rate'][$last_rate]['#attributes'] as $key => $value) {
echo "$value ";
}
Which will output:
AMD 614.98298701028 0
If your array will always contain the array values under rate, you can retrieve the last element of the rate array by using end($newArray['rate']).
To output a CSV style string you can simply use implode(', ', $last['#attributes']) or another desired method, such as foreach, to display the values from the last element.
Example: https://3v4l.org/FNuuZ
if ($last = end($newArray['rate'])) {
echo implode(', ', $last['#attributes']);
}
Result:
AMD, 614.98298701028, 0
I have an array where I want to group items having match strings in key.
My array looks like this:
Array
(
[ALL_trading_enabled] => 1
[ALL_enabled_pairs] => ALL
[ALL_max_trading_pairs] => 10
[SNGLSBTC_DCA_enabled] =>
[SNGLSBTC_sell_only_mode] => 1
[SNGLSBTC_sell_value] => 0.28
[SNGLSBTC_trailing_profit] => 0.009
[ENJBTC_DCA_enabled] =>
[ENJBTC_sell_only_mode] => 1
[ENJBTC_sell_value] => 0.28
[ENJBTC_trailing_profit] => 0.009
[BCPTBTC_DCA_enabled] =>
[BCPTBTC_sell_only_mode] => 1
[BCPTBTC_sell_value] => 0.28
[BCPTBTC_trailing_profit] => 0.009
)
I want to group the items that have the same string. What I want looks like this:
Array
(
[0] => Array(
[ALL_trading_enabled] => 1
[ALL_enabled_pairs] => ALL
[ALL_max_trading_pairs] => 10
)
[1] => Array(
[SNGLSBTC_DCA_enabled] =>
[SNGLSBTC_sell_only_mode] => 1
[SNGLSBTC_sell_value] => 0.28
[SNGLSBTC_trailing_profit] => 0.009
)
[2] => Array(
[ENJBTC_DCA_enabled] =>
[ENJBTC_sell_only_mode] => 1
[ENJBTC_sell_value] => 0.28
[ENJBTC_trailing_profit] => 0.009
)
[3] => Array(
[BCPTBTC_DCA_enabled] =>
[BCPTBTC_sell_only_mode] => 1
[BCPTBTC_sell_value] => 0.28
[BCPTBTC_trailing_profit] => 0.009
)
)
Any help to achieve this? Or better yet if I can assign the match as the key for the created group.
Array(
[ALL] => Array(
//items here
)
[SNGLSBTC] => Array(
//items here
)
)
Explode on _ and get the first portion, use as the key and add to that array:
foreach($array as $key => $value) {
$new_key = explode('_', $key)[0];
$result[$new_key][$key] = $value;
}
If needed to re-index (after your edit you don't need this):
$result = array_values($result);
Right now, I have array sets like these:
[9] => Array
(
[sl] => 10
[upload_dt] => 2015-04-15 14:39:58
[total_files] => 3
[file_name] => logo01.png
[remarks] => qqq
[status] => pending
[download_file] => http://localhost/web/download_file21
)
[10] => Array
(
[sl] => 10
[upload_dt] => 2015-04-15 14:39:58
[total_files] => 3
[file_name] => face.jpg
[remarks] => 5645645
[status] => pending
[download_file] => http://localhost/web/download_file22
)
[11] => Array
(
[sl] => 10
[upload_dt] => 2015-04-15 14:39:58
[total_files] => 3
[file_name] => ID_11401871809904(15).pdf
[remarks] => 567567
[status] => pending
[download_file] => http://localhost/web/download_file23
)
Now, I need to merge same values in some of the indices into one arrays.
The merged array values should look like this in the end.
[9] => Array
(
[sl] => 10
[upload_dt] => 2015-04-15 14:39:58
[total_files] => 3
[file_name] => logo01.png , face.jpg, ID_11401871809904(15).pdf
[remarks] => qqq, 5645645 , 567567
[status] => pending, pending ,pending
[download_file] => http://localhost/web/download_file21,
http://localhost/web/download_file22,
http://localhost/web/download_file23
)
Now, I tried using array_merge but it didn't actually work in this case.
Solution will be like this:
<?php
$result = array();
$ar1[9] = Array
(
'sl' => 10,
'upload_dt' => '2015-04-15 14:39:58',
'total_files' => 3,
'file_name' => 'logo01.png',
'remarks' => 'qqq',
'status' => 'pending',
'download_file' => 'http://localhost/web/download_file21'
);
$ar1[10] = Array
(
'sl' => 10,
'upload_dt' => '2015-04-15 14:39:58',
'total_files' => 3,
'file_name' => 'face.jpg',
'remarks' => '5645645',
'status' => 'pending',
'download_file' => 'http://localhost/web/download_file22'
);
$ar1[11] = Array
(
'sl' => 10,
'upload_dt' => '2015-04-15 14:39:58',
'total_files' => 3,
'file_name' => 'ID_11401871809904(15).pdf',
'remarks' => 567567,
'status' => 'pending',
'download_file' => 'http://localhost/web/download_file23'
);
foreach($ar1 as $record){
$keys = array_keys($record);
foreach($keys as $key) {
if(array_key_exists($key,$result)){
$valeInKey = explode(',', $result[$key]);
if (!in_array($record[$key], $valeInKey)){
$result[$key]= $result[$key] .",".$record[$key];
}
} else{
$result[$key]= $record[$key];
}
}
}
echo"<pre>";print_r($result);exit;
?>
You're actually merging strings inside those arrays so just ditch the array_merge idea, and just use a simple loop then use the key as your basis to concatenate strings. Rough example:
$result = array();
foreach($array as $values) {
if(!isset($result[$values['sl']])) {
$result[$values['sl']] = $values; // initial
} else {
foreach(array('file_name', 'remarks', 'status', 'download_file') as $field) {
$result[$values['sl']][$field] .= ", {$values[$field]}";
}
}
}
Sample Output
array_merge won't work, because the keys would overwrite each other.
A solution would be to merge them with a the help of a foreach. Something like this:
$new = array();
foreach($arr as $key => $value) {
$new[$key] .= ", ".$value;
}
But you would have multiple entries for every single array you want to merge. If you just want to have them for a few, you have to check the key and do something accordingly.
I just found out how to loop an array based on another array, but my problem is that if the second array is just 1 object than it works fine but I want to make it work with two objects.
Here is an example how it do works,
$shorten = array(
0 => 'ECAR',
1 => 'CCAR',
2 => 'ICAR',
3 => 'SCAR',
4 => 'FCAR',
5 => 'PCAR',
);
$data = array(
'Hertz' => array(
'ECAR' => '49.21',
'CCAR' => '71.04',
'ICAR' => '89.58',
'SCAR' => '100.00',
)
),
'Avis' => array(
'ECAR' => '412.00',
'CCAR' => '347.00',
'ICAR' => '285.00',
'SCAR' => '224.00',
'FCAR' => '165.00',
'PCAR' => '100.00',
)
),
);
// default array as the base
$shorten = array_combine($shorten, array_fill(0, count($shorten), 'n/a'));
foreach($data as &$array) {
// merge to get set members
$array = array_merge($shorten, $array);
}
unset($array);
print_r($data);
But I want to make it work with this one,
$shorten = array(
0 => 'ECAR',
1 => 'CCAR',
2 => 'ICAR',
3 => 'SCAR',
4 => 'FCAR',
5 => 'PCAR',
);
$data = array(
'Hertz' => array(
'NYCT01' => array(
'ECAR' => '49.21',
'CCAR' => '71.04',
'ICAR' => '89.58',
'SCAR' => '100.00',
)
),
'Avis' => array(
'NYCT01' => array(
'ECAR' => '412.00',
'CCAR' => '347.00',
'ICAR' => '285.00',
'SCAR' => '224.00',
'FCAR' => '165.00',
'PCAR' => '100.00',
)
),
);
// default array as the base
$shorten = array_combine($shorten, array_fill(0, count($shorten), 'n/a'));
foreach($data as $firstArray) {
foreach($firstArray as &$array){
// merge to get set members
$array = array_merge($shorten, $array);
}
}
unset($array);
print_r($data);
And this is what I want it to be,
Array
(
[Hertz] => Array
(
[ECAR] => 49.21
[CCAR] => 71.04
[ICAR] => 89.58
[SCAR] => 100.00
[FCAR] => n/a
[PCAR] => n/a
)
[Avis] => Array
(
[ECAR] => 412.00
[CCAR] => 347.00
[ICAR] => 285.00
[SCAR] => 224.00
[FCAR] => 165.00
[PCAR] => 100.00
)
)
foreach($data AS $company => $nyc){
$inner = $nyc['NYCT01'];
foreach($shorten AS $car){
if(array_key_exists($car, $inner)){
$output[$company][$car] = $inner[$car];
}else {
$output[$company][$car] = "n/a";
}
}
}
Just loop through the data and check if the key of any of the cars exists inside the NYCT01 array, if it does set the value, else, "n/a".
My output:
Array
(
[Hertz] => Array
(
[ECAR] => 49.21
[CCAR] => 71.04
[ICAR] => 89.58
[SCAR] => 100.00
[FCAR] => n/a
[PCAR] => n/a
)
[Avis] => Array
(
[ECAR] => 412.00
[CCAR] => 347.00
[ICAR] => 285.00
[SCAR] => 224.00
[FCAR] => 165.00
[PCAR] => 100.00
)
)
Ok, got it work this is the real code I figured,
foreach($data as $company => $nyc){
foreach($nyc as $inner => $s){
foreach($shorten as $car){
if(array_key_exists($car, $nyc[$inner])){
$output[$company][$car] = $nyc[$inner][$car];
}else {
$output[$company][$car] = "n/a";
}
}
}
}
Thanks so much for your help Marcus,
Good luck.