Array manipulation: Convert one array to another - php

For a few hours, I lost myself in an array.
I have something like this:
$results = [
"User_1" = [
"Step_1" = "accepted",
"Step_2" = "accepted",
"Step_3" = "waiting",
"Step_4" = "refused"
],
"User_2" = [
"Step_1" = "waiting",
"Step_2" = "accepted",
"Step_3" = "accepted",
"Step_4" = "refused"
],
];
I need to count (and have the sum) of all the "status" for a specific "Step".
In this case, I wish to have :
$steps = [
"Step_1" = [
'acceptedSum' => 1,
'refusedSum' => 0,
'waitingSum' => 1
],
"Step_2" =[
'acceptedSum' => 2,
'refusedSum' => 0,
'waitingSum' => 0
],
"Step_3" =[
'acceptedSum' => 1,
'refusedSum' => 0,
'waitingSum' => 1
],
"Step_4" =[
'acceptedSum' => 0,
'refusedSum' => 0,
'waitingSum' => 2
],
];
[ Nota: Number of User is not defined (1 to N) and number of Step too (1 to 4) ]
Any help will be appreciated :)
Thanks to you.

Try this, see if it works or not.
$steps = array();
$count = 0;
$keys = array_keys(current($results));
foreach($keys as $key){
$accepted = 0;
$refused = 0;
$waiting = 0;
foreach ($results as $result) {
foreach ($result as $k => $v) {
if ($key==$k&&$v == 'accepted') {
$accepted++;
}
if ($key==$k&&$v == 'refused') {
$refused++;
}
if ($key==$k&&$v == 'accepted') {
$waiting++;
}
}
}
$new_array = [
'acceptedSum' => $accepted,
'refusedSum' => $refused,
'withoutAnswerSum' => $waiting
];
$steps[$key] = $new_array;
}
print_r($steps);

You could create the existing keys dynamically. The missing keys you could add with a value of 0;
$results = [
"User_1" => [
"Step_1" => "accepted",
"Step_2" => "accepted",
"Step_3" => "waiting"
],
"User_2" => [
"Step_1" => "waiting",
"Step_2" => "accepted",
"Step_3" => "accepted"
],
"User_3" => [
"Step_1" => "refused",
"Step_2" => "refused",
"Step_3" => "waiting"
]
];
$steps = [];
$status = [];
foreach ($results as $result) {
foreach ($result as $key => $r) {
if (!array_key_exists($key, $steps)) {
$steps[$key] = [];
}
if (!array_key_exists($r."Sum", $steps[$key])) {
$steps[$key][$r."Sum"] = 0;
}
$steps[$key][$r."Sum"]++;
$status[] = $r;
}
}
foreach (array_unique($status) as $au) {
foreach ($steps as &$step) {
if (!array_key_exists($au."Sum", $step)) {
$step[$au."Sum"] = 0;
}
}
}
print_r($steps);
Php output demo

I think the output in your question is wrong, but are you looking for something like this
<?php
$results = [
"User_1" => [
"Step_1" => "accepted",
"Step_2" => "accepted",
"Step_3" => "waiting"
],
"User_2" => [
"Step_1" => "waiting",
"Step_2" => "accepted",
"Step_3" => "accepted"
],
"User_3" => [
"Step_1" => "refused",
"Step_2" => "refused",
"Step_3" => "waiting"
]
];
function sumByStatus($array, $status) {
$filtered_array = array_filter($array,function($value) use ($status) {
return $value === $status;
});
return count($filtered_array);
}
$newResult = array_map(function($item) {
return [
'acceptedSum' => sumByStatus($item, 'accepted'),
'refusedSumF' => sumByStatus($item, 'refused'),
'withoutAnswerSum' => sumByStatus($item, 'waiting')
];
}, $results);
print_r($newResult);
The output is
Array
(
[User_1] => Array
(
[acceptedSum] => 2
[refusedSum] => 0
[withoutAnswerSum] => 1
)
[User_2] => Array
(
[acceptedSum] => 2
[refusedSum] => 0
[withoutAnswerSum] => 1
)
[User_3] => Array
(
[acceptedSum] => 0
[refusedSum] => 2
[withoutAnswerSum] => 1
)
)

Related

PHP looping recursive function

I had this looping function and what it does to fetch data then display the result in json format. In $subArray[] i try to call the looping function again so it can read if got any sub-nodes underneath. But seem the result not display as I expected to be.
function recursiveNode($ledgerID,$accountID){
global $ehorsObj;
$subArray = array();
$query_get_subchild = " SELECT accountLedgerID, accountID, accountMainID, accountName, active
FROM tblAccAccounts
WHERE accountMain = 'y'
AND accountSub = 'y'
AND accountMainID = '".$accountID."'
AND accountLedgerID = '".$ledgerID."'
ORDER BY accountName
";
$GetResult = $ehorsObj->FetchData($query_get_subchild, $ehorsObj->DEFAULT_PDO_CONNECTIONS);
while ($row3 = $GetResult->fetch()) {
$subArray[] = array('accountLedgerID' => $row3['accountLedgerID'], 'accountID' => $row3['accountID'], 'accountMainID' => $row3['accountMainID'], 'accountName' => $row3['accountName'], 'active' => $row3['active'], 'items' => recursiveNode($ledgerID, $row3['accountID']));
}
header("Content-type: application/json");
$result = json_encode($subArray);
echo $result;
}
it show the result (as image below)
and the result I expected to be like this
[
{
accountLedgerID: "LA1",
accountID: "LA95",
accountMainID: "LA5",
accountName: "SubGroup RunDeposit 1",
active: "y"
},
{
accountLedgerID: "LA1",
accountID: "LA2",
accountMainID: "LA5",
accountName: "SubGroup RunDeposit 2",
active: "y",
item: [
{
accountLedgerID: "LA1",
accountID: "LA125",
accountMainID: "LA2",
accountName: "Sub x2 Group RunDeposit 2",
active: "y",
items: [
{
accountLedgerID: "LA1",
accountID: "LA6",
accountMainID: "LA125",
accountName: "Sub x3 Group RunDeposit 2",
active: "y",
items: [ ]
}
]
}
]
}
]
function fetch_account ($dbresult, $ledgerID, $accountID) {
$result = array_filter($dbresult, function ($something) use ($ledgerID, $accountID) {
if ( $something['accountMainID'] == $accountID && $something['accountLedgerID'] == $ledgerID ) {
return true;
}
return false;
});
return array_values($result);
}
function recursiveNode($ledgerID,$accountID){
$testArray = [
[
'accountLedgerID' => 'LA1',
'accountID' => 'LA95',
'accountMainID' => 'LA5',
'accountName' => 'SubGroup RunDeposit 1',
'active' => 'y'
],
[
'accountLedgerID' => 'LA1',
'accountID' => 'LA2',
'accountMainID' => 'LA5',
'accountName' => 'SubGroup RunDeposit 2',
'active' => 'y'
],
[
'accountLedgerID' => 'LA1',
'accountID' => 'LA125',
'accountMainID' => 'LA2',
'accountName' => 'Sub x2 Group RunDeposit 2',
'active' => 'y'
],
[
'accountLedgerID' => 'LA1',
'accountID' => 'LA6',
'accountMainID' => 'LA125',
'accountName' => 'Sub x3 Group RunDeposit 2',
'active' => 'y'
]
];
$someArray = fetch_account($testArray, $ledgerID, $accountID);
$subArray = array();
$i = 0;
while (!empty($someArray[$i]) && $row3 = $someArray[$i]) {
$subArray[] = array(
'accountLedgerID' => $row3['accountLedgerID'],
'accountID' => $row3['accountID'],
'accountMainID' => $row3['accountMainID'],
'accountName' => $row3['accountName'],
'active' => $row3['active'],
'items' => recursiveNode($ledgerID, $row3['accountID'])
);
$i++;
}
return $subArray;
}
$myArray = recursiveNode('LA1', 'LA5');
$result = json_encode($myArray);
echo $result;
Breaking down the problem first, I think the recursive function isn't returning anything. I think this is indicative when your result has 'items' as null.

Invoices are not inserted in quickbook

i'm trying to create invoice with multiple product/item in quickbook with help of this code https://github.com/IntuitDeveloper/SampleApp-CRUD-PHP/blob/master/CRUD_Examples/Invoice/InvoiceCreate.php but variable $resultingObj always gives num value when data are takes forloop but when passing only one product details successfully create invoice.
i applied this method Inserting contents of array into object not working gives as answer but still null.
invoice:
$num = 1;
$Lines = [];
foreach ($json as $rec) {
foreach ($rec['products'] as $pro) {
$productDetails = getItemObj($pro, $collection1);
if ($productDetails == 'Error') {
continue;
}
$taxDetails = getTaxObj($dataService, $pro);
if ($taxDetails == 'Error') {
continue;
}
$Lines[] =
[
"Id" => $num,
"Amount" => $pro['amount'],
"Description" => $pro['productDescription'],
"DetailType" => "SalesItemLineDetail",
"SalesItemLineDetail" => [
"ItemRef" => [
"value" => $productDetails->Id,
],
"TaxCodeRef" => [
"value" => $taxDetails->Id
],
"UnitPrice" => $pro['unitPrice'],
"Qty" => $pro['quantity'],
]
];
$num++;
}
$Lines[] = [
"Amount" => $rec['invoiceTotal'],
"DetailType" => "SubTotalLineDetail",
"SubTotalLineDetail" => []
];
$customerRef = getCustomerObj($dataService, $rec['clientName']);
$invoiceObj = Invoice::create([
"Line" => $Lines,
"CustomerRef" => [
"value" => $customerRef->Id
],
]);
$resultingInvoiceObj = $dataService->Add($invoiceObj);

Group subarray data by one column and form comma-separated values from the secondary value in each group [duplicate]

This question already has answers here:
Group subarrays by one column, make comma-separated values from other column within groups
(2 answers)
Closed last month.
I have a two dimensional array which needs to be restructured. Rows must be grouped by date values, and within each group, the name values should be formed into a single comma-delimited string.
My input:
$missedFridgeLog = [
[
"date" => "01/01/18",
"name" => "Medicine"
],
[
"date" => "01/01/18",
"name" => "Drugs"
],
[
"date" => "02/01/18",
"name" => "Medicine"
],
[
"date" => "02/01/18",
"name" => "Drugs"
]
];
I have tried implementing a solution from Implode or join multidimentional array with comma, but it did not work as desired.
Desired output:
[
[
'date' => '01/01/18',
'name' => 'Medicine,Drugs',
],
[
'date' => '02/01/18',
'name' => 'Medicine,Drugs',
]
]
$missedFridgeLog = [
[
"date" => "01/01/18",
"name" => "Medicine"
],[
"date" => "01/01/18",
"name" => "Drugs"
]
[
"date" => "02/01/18",
"name" => "Medicine"
],
[
"date" => "02/01/18",
"name" => "Drugs"
]
];
$byDates = [];
foreach ($missedFridgeLog as $mfg) {
$byDates[$mfg['date']][] = $mfg['name'];
}
$res = [];
foreach ($byDates as $date => $name) {
$res[] = [
'name' => join(',',$name),
'date' => $date
];
}
var_dump($res);
You need to search key, value pair everytime you make a insert or update to result array. use this function() to search associate array. If match then update with additional name info else make a new insert to result array.
function filter_array($array){
///$array your previous array data
$result = array();
foreach($array["missedFridgeLog"] as $m){
$flag = true;
foreach($result as $k=>$r) {
if (is_in_array($r, "date", $m["date"]) == "yes") {
$result[$k]["name"] = $r["name"] . ',' . $m["name"];
$flag = false;
break;
}
}
if($flag==true){
$result[] = $m;
}
}
return array("missedFridgeLog"=>$result);
}
function is_in_array($array, $key, $key_value){
$within_array = 'no';
foreach( $array as $k=>$v ){
if( is_array($v) ){
$within_array = is_in_array($v, $key, $key_value);
if( $within_array == 'yes' ){
break;
}
} else {
if( $v == $key_value && $k == $key ){
$within_array = 'yes';
break;
}
}
}
return $within_array;
}
May be this is not the best way to do this, but it will help
$arr['missedFridgeLog'] = [
[
'date' => '01/01/18',
'name' => 'Medicine1'
],
[
'date' => '02/01/18',
'name' => 'New Medicine2'
],
[
'date' => '01/01/18',
'name' => 'Drugs1'
],
[
'date' => '02/01/18',
'name' => 'Medicine2'
],
[
'date' => '01/01/18',
'name' => 'New Drugs1'
],
[
'date' => '02/01/18',
'name' => 'Drugs2'
]
];
echo "<pre>";
$new_arr = array();
$date = array();
foreach ($arr['missedFridgeLog'] as $k => $a) {
if (in_array($a['date'], $date))
continue;
$new_arr[$k]['name'] = $a['name'];
$new_arr[$k]['date'] = "";
foreach ($arr[missedFridgeLog] as $key => $val) {
if ($key != $k) {
if ($a['date'] == $val['date']) {
$date[] = $new_arr[$k]['date'] = $a['date'];
$new_arr[$k]['name'] .= ", " . $val['name'];
}
}
}
if (empty($new_arr[$k]['date']))
unset($new_arr[$k]);
}
print_r($new_arr);
You can try below :-
Input array :-
$chkArray = [
'missedFridgeLog' => [
'0' => [
'date' => '01/01/18',
'name' => 'Medicine'
],
'1' => [
'date' => '01/01/18',
'name' => 'Drugs'
],
'2' => [
'date' => '02/01/18',
'name' => 'Medicine'
],
'3' => [
'date' => '02/01/18',
'name' => 'Drugs'
],
'4' => [
'date' => '02/01/18',
'name' => 'My Drugs'
]
]
];
$i = 0;
$finalarray = array();
foreach($chkArray['missedFridgeLog'] as $key=>$value) {
$checkExist = array_search($value['date'], array_column($finalarray, 'date'), true);
if($checkExist !== false) {
$finalarray[$checkExist]['name'] = $finalarray[$checkExist]['name'].','.$value['name'];
}
else {
$finalarray[$i]['date'] = $value['date'];
$finalarray[$i]['name'] = $value['name'];
$i++;
}
}
print_r($finalarray);
OutPut :-
Array
(
[0] => Array
(
[date] => 01/01/18
[name] => Medicine,Drugs
)
[1] => Array
(
[date] => 02/01/18
[name] => Medicine,Drugs,My Drugs
)
)
Do not use:
More than one loop,
Nested loops,
in_array(), or
array_search().
You only need one loop to apply temporary grouping keys. When a date/group is encountered after the first time, append its name value to the group's name value. When finished iterating, re-index the array.
Code: (Demo)
$result = [];
foreach ($missedFridgeLog as $row) {
if (!isset($result[$row['date']])) {
$result[$row['date']] = $row;
} else {
$result[$row['date']]['name'] .= ",{$row['name']}";
}
}
var_export(array_values($result));
Output:
array (
0 =>
array (
'date' => '01/01/18',
'name' => 'Medicine,Drugs',
),
1 =>
array (
'date' => '02/01/18',
'name' => 'Medicine,Drugs',
),
)

Array Operations to add / remove entries from 1 to another

I have 2 sets of array:
Data:
$data = [
[
'company_code' => 'ABC',
'supplier_codes' => [
'S-2',
'S-3',
'S-5',
],
],
];
Source (from database):
$database = [
'company_code' => 'ABC',
'suppliers' => [
[
'code' => 'S-1',
],
[
'code' => 'S-2',
'reference' => '12345'
],
[
'code' => 'S-3',
],
[
'code' => 'S-4',
'reference' => 'some string',
]
],
];
What I need to achieve:
If a supplier code is missing in $data but exists in $database,
remove it from $database.
If a supplier code exists in $data but missing in $database, add it into $database
The output of the example here should be as follows:
$output = [
'company_code' => 'ABC',
'suppliers' => [
[
'code' => 'S-2',
'reference' => '12345'
],
[
'code' => 'S-3',
],
[
'code' => 'S-5',
]
],
];
I was thinking of removing the suppliers subarray, then reconstruct the structure based on the data from supplier_codes. But the problem is some of the entries in suppliers may have an optional field called reference.
Try this
<?php
$data = [
[
'company_code' => 'ABC',
'supplier_codes' => ['S-2','S-3','S-5'],
],
];
$database = [
'company_code' => 'ABC',
'suppliers' => [
[
'code' => 'S-1',
],
[
'code' => 'S-2',
'reference' => '12345'
],
[
'code' => 'S-3',
],
[
'code' => 'S-4',
'reference' => 'some string',
]
],
];
foreach($database['suppliers'] as $k=>$v){
foreach($data as $kd=>$vd){
$valueremove = false;
$removeIndex = '';
foreach($vd['supplier_codes'] as $key=>$val){
if($val == $v['code']){
$valueremove = false;
$removeIndex = '';
break;
} else {
$valueremove = true;
$removeIndex = $k;
}
}
if($valueremove == true){
unset($database['suppliers'][$removeIndex]);
} else {
$valueinsert = false;
foreach($data as $kd=>$vd){
foreach($vd['supplier_codes'] as $key=>$val){
foreach($database['suppliers'] as $kc=>$vc){
if($val == $vc['code']){
$valueinsert = false;
$insertIndex = '';
$insertVal = '';
break;
} else {
$valueinsert = true;
$insertIndex = count($database['suppliers'])+1;
$insertVal = $val;
}
}
if($valueinsert == true){
$database['suppliers'][$insertIndex] = array('code'=>$insertVal);
}
}
}
}
}
}
echo "<PRE>"; print_r($database);
I end up solving my problem this way:
$result = $database;
$result['suppliers'] = [];
foreach($data as $tag) {
foreach($tag['supplier_codes'] as $code) {
$found = false;
foreach($database['suppliers'] as $supplier) {
if($supplier['code'] === $code) {
$result['suppliers'][] = $supplier;
$found = true;
}
}
if(!$found) {
$result['suppliers'][] = ['code' => $code];
}
}
}
Output of print_r($result);:
Array
(
[company_code] => ABC
[suppliers] => Array
(
[0] => Array
(
[code] => S-2
[reference] => 12345
)
[1] => Array
(
[code] => S-3
)
[2] => Array
(
[code] => S-5
)
)
)

How can i get the value outside foreach without using array?

I want to get calleridnum without using array . Is this possible?
or is there other way to do this ?
I have this code :
$participants = [
[ 'calleridnum' => 1,
'test' => 'yay'
],
[ 'calleridnum' => 2,
'test' => 'yay'
],
[ 'calleridnum' => 3,
'test' => 'yay'
]
];
$conferance_participants = [
[ 'uid' => 1,
'test' => 'yay2',
'dit' => 'deze'
],
[ 'uid' => 2,
'test' => 'test',
'dit' => 'wew'
]
];
foreach ($participants as $key=>$p) {
foreach ($conferance_participants as $key=>$cp) {
if ($p['calleridnum'] == $cp['uid']) {
$calleridnum[] = $p['calleridnum'];
}
}
}
print_r( $calleridnum );
My output is:
Array ( [0] => 1 [1] => 2 )
but I want the output to be like this
1,2
Use implode() outside of foreach loop
echo $str = implode (",", $calleridnum);
Try this: Implode your array to be converted into string.
$calleridnum= [];
foreach ($participants as $key=>$p) {
foreach ($conferance_participants as $key=>$cp) {
if ($p['calleridnum'] == $cp['uid']) {
$calleridnum[] = $p['calleridnum'];
}
}
}
$result = implode(',', $calleridnum);
echo $result;
I'll simply use array_intersect,array_column along with implode as
echo implode(',', array_intersect(array_column($conferance_participants,'uid'), array_column($participants,'calleridnum')));
Demo

Categories