I have the following string thatI convert into a json array. All I am trying to do put together keys with the same value for id_number and sum the amount to each of these keys and print the resulting value outside the loop.
$response = '{
"nhif":[
{
"id_number":"AA112233",
"amount":"5",
"date":"2018-09-14T20:18:50"
},
{
"id_number":"AA112233",
"amount":"5",
"date":"2018-09-14T19:59:14"
},
{
"id_number":"AA112233",
"amount":"5",
"date":"2018-09-14T09:07:34"
},
{
"id_number":"AA112233",
"amount":"5",
"date":"2018-09-14T09:04:27"
},
{
"id_number":"12345678",
"amount":"5",
"date":"2018-09-14T09:04:21"
}
]
}';
$json_response = json_decode($response, true);
//Start NHIF
foreach ($json_response['nhif'] as $nhif) {
echo ''.$nhif{"id_number"}.' '.$nhif{"amount"}.' '.$nhif{"date"}.'<br/>';
}
//END NHIF
My expected output is:
#id_number #amount
AA112233 20
12345678 5
Any workaround this?
You can use array_reduce to sum the amount values by id_number:
$sums = array_reduce($json_response['nhif'], function ($c, $i) {
$c[$i['id_number']] = (isset($c[$i['id_number']]) ? $c[$i['id_number']] : 0) + $i['amount'];
return $c;
}, array());
print_r($sums);
Output:
AA112233 20
12345678 5
Demo on rextester
If you're using PHP7, this
isset($c[$i['id_number']]) ? $c[$i['id_number']] : 0
can be simplified to
$c[$i['id_number']] ?? 0
You can do solve this problem using an array
$response = '{
"nhif":[
{
"id_number":"AA112233",
"amount":"5",
"date":"2018-09-14T20:18:50"
},
{
"id_number":"AA112233",
"amount":"5",
"date":"2018-09-14T19:59:14"
},
{
"id_number":"AA112233",
"amount":"5",
"date":"2018-09-14T09:07:34"
},
{
"id_number":"AA112233",
"amount":"5",
"date":"2018-09-14T09:04:27"
},
{
"id_number":"12345678",
"amount":"5",
"date":"2018-09-14T09:04:21"
}
]
}';
$json_response = json_decode($response, true);
$results = array(); // will map the unique keys with it's sum
//Start NHIF
foreach ($json_response['nhif'] as $nhif) {
if(!isset($results[$nhif['id_number']])) // new key initialized
$results[$nhif['id_number']] = $nhif['amount'];
else
$results[$nhif['id_number']] += $nhif['amount'];
}
//END NHIF
foreach($results as $key => $value) {
echo $key .' '.$value; // printing the result
}
Sort the array [If the data is not sorted otherwise do not need to sort].
Do the for loop and summation.
Try with this code sample, there are many other ways to solve this problem depending on problem solving skill.
$response = '{
"nhif":[
{
"id_number":"AA112233",
"amount":"5",
"date":"2018-09-14T20:18:50"
},
{
"id_number":"AA112233",
"amount":"5",
"date":"2018-09-14T19:59:14"
},
{
"id_number":"AA112233",
"amount":"5",
"date":"2018-09-14T09:07:34"
},
{
"id_number":"AA112233",
"amount":"5",
"date":"2018-09-14T09:04:27"
},
{
"id_number":"12345678",
"amount":"5",
"date":"2018-09-14T09:04:21"
}
]
}';
$data = json_decode($response, true);
usort($data['nhif'], function($a, $b) {
return $b['id_number'] <=> $a['id_number'];
});
//Start NHIF
$amount = 0;
$id_number = null;
foreach($data['nhif'] as $nhif) {
if(($nhif['id_number'] != $id_number) && ($id_number != null)){
echo $id_number. "\t". $amount . "<br />";
$id_number = $nhif['id_number'];
$amount = $nhif['amount'];
}
else{
$id_number = $nhif['id_number'];
$amount = $amount + $nhif['amount'];
}
// echo ''.$nhif{"id_number"}.' '.$nhif{"amount"}.' '.$nhif{"date"}.'<br />';
}
echo $id_number. "\t". $amount . "<br />";
//END NHIF
You could create a new array for example $r and check if the key for $nhif['id_number'] already exists.
If it does, add value for $nhif['amount']using +=. If it does not, set the value using =
This example uses the ternary ?: operator:
$r = [];
foreach ($json_response['nhif'] as $nhif) {
isset($r[$nhif['id_number']]) ? $r[$nhif['id_number']] += $nhif['amount'] : $r[$nhif['id_number']] = $nhif['amount'];
}
Demo
Related
This is my array
array(
['studentId'=>"M100030","isbn"=>"0199535566",'price'=>"15.00"],
['studentId'=>"M100030","isbn"=>"0199535566",'price'=>"13.50"],
['studentId'=>"M100030","isbn"=>"0143105426",'price'=>"20.00"],
['studentId'=>"M100035","isbn"=>"1604501480",'price'=>"21.00"],
['studentId'=>"M100035","isbn"=>"1604501480",'price'=>"23.00"],
['studentId'=>"M100035","isbn"=>"0199535566",'price'=>"14.00"],
['studentId'=>"M103233","isbn"=>"0061964360",'price'=>"18.50"],
);
I want to group the studentId and isbn then sum up the price to JSON
{
"M100030":{
"0199535566":{
"amount":"28.50"
},
"0143105426":{
"amount":"20.00"
}
},
"M100035":{
"1604501480":{
"amount":"44.00"
},
"0199535566":{
"amount":"14.00"
}
},
"M103233":{
"0061964360":{
"amount":"18.50"
}
}
}
The method I tried so far to group the studentId and isbn, but not able to get the expected result. Anyone can correct my code?
foreach ($check['rentout'] as $key=> $values)
{
$keys = $values['studentId'];
if (!array_key_exists($keys,$trx)){
$trx[$keys] = array('isbn'=>$values['isbn'],'amount'=>$values['price']);
}else{
$trx[$keys]['amount'] = $trx[$keys]['amount']+$values['price'];
}
}
$students = array(
['studentId'=>"M100030","isbn"=>"0199535566",'price'=>"15.00"],
['studentId'=>"M100030","isbn"=>"0199535566",'price'=>"13.50"],
['studentId'=>"M100030","isbn"=>"0143105426",'price'=>"20.00"],
['studentId'=>"M100035","isbn"=>"1604501480",'price'=>"21.00"],
['studentId'=>"M100035","isbn"=>"1604501480",'price'=>"23.00"],
['studentId'=>"M100035","isbn"=>"0199535566",'price'=>"14.00"],
['studentId'=>"M103233","isbn"=>"0061964360",'price'=>"18.50"],
);
I Created variable $res and I looped over $students and get the $student_id and do a test if there is no isbn for this student, If So set their amount to the initial value, and loop again if we find it again accumulate its prices to amount, and do this again and again to all students in the array.
$res = [];
foreach ($students as $key => $student) {
$student_id = $student['studentId'];
if (!isset($res[$student_id][$student["isbn"]])){
$res[$student_id][$student["isbn"]]["amount"] = $student['price'];
}else{
$res[$student_id][$student["isbn"]]["amount"] += $student['price'];
}
}
echo "<pre>";
echo json_encode($res, JSON_PRETTY_PRINT);
Print(as excpected)
{
"M100030": {
"0199535566": {
"amount": 28.5
},
"0143105426": {
"amount": "20.00"
}
},
"M100035": {
"1604501480": {
"amount": 44
},
"0199535566": {
"amount": "14.00"
}
},
"M103233": {
"0061964360": {
"amount": "18.50"
}
}
}
I amnot familiar php arrays. Therefore I couldn't solve that problem :
My data comes from database. I didn't post database connection parts, they work perfectly. As I understand I need to use multidimensional array. My Json format should be like this
{
"monthly":[
{
"id":1,
"name":"This is a JSON event",
"startdate":"2016-9-15",
"enddate":"2016-9-15",
"starttime":"12:00",
"endtime":"2:00",
"color":"#FFB128",
"url":""
},
{
"id":2,
"name":"This is a JSON event",
"startdate":"2019-3-25",
"enddate":"2019-3-25",
"starttime":"12:00",
"endtime":"23:00",
"color":"#EF44EF",
"url":""
}
]
}
My PHP script (relevant part) :
try {
$q = "SELECT * FROM eventcalendar";
$res = $db->prepare($q);
$res->execute();
if ($res->rowCount() != 0) {
$data = array('monthly' => array());
$push_array = array();
foreach ($res as $key) {
$data['monthly']['id'] = $key['id'];
$data['monthly']['name'] = $key['name'];
$data['monthly']['startdate'] = $key['startdate'];
$data['monthly']['enddate'] = $key['startdate'];
$data['monthly']['color'] = $key['color'];
$data['monthly']['starttime'] = 12;
$data['monthly']['endtime'] = 12;
$data['monthly']['url'] = "";
array_push($push_array, $data);
}
file_put_contents('../js/events.json', json_encode($push_array));
echo('<div class="alert alert-success resultsuccess" ><h4 class="alert-heading">Successful!</h4></div>');
}
} catch (Exception $e) {
echo('<div class="alert alert-danger resultsuccess" >'.'Error: '.$e->getMessage().'</div>');
}
I get that JSON format
[
{
"monthly":{
"id":"1",
"name":"test1",
"startdate":"2019-03-29",
"enddate":"2019-03-29",
"color":"#ffb128",
"starttime":12,
"endtime":12,
"url":""
}
},
{
"monthly":{
"id":"2",
"name":"test2",
"startdate":"2019-03-29",
"enddate":"2019-03-29",
"color":"#4263e6",
"starttime":12,
"endtime":12,
"url":""
}
}
]
Thanks for reading...
Your problem is that you are creating new arrays with a monthly index on each pass through your loop, instead of pushing the new data into the existing monthly array. Try this instead:
if ($res->rowCount() != 0) {
$push_array = array('monthly' => array());
$data = array();
foreach ($res as $key) {
$data['id'] = $key['id'];
$data['name'] = $key['name'];
$data['startdate'] = $key['startdate'];
$data['enddate'] = $key['startdate'];
$data['color'] = $key['color'];
$data['starttime'] = 12;
$data['endtime'] = 12;
$data['url'] = '';
array_push($push_array['monthly'], $data);
}
I have a list of financial launch. Each launch may or may not have multiple payments. So for every financial launch I look for a list of payments. I would like this list to be within its corresponding financial launch.
My complete function:
public function customerInvoice()
{
$_customer = filtra_int($this->input->post('cliente_id'));
$this->redireciona_id_nula($_customer, $this->url . '/ficha');
$_view = [];
$this->load->helper(['filter', 'string', 'currency', 'validate', 'phone']);
$_view['glyph'] = 'user';
$_view['enterprise'] = $this->enterprise;
$_view['buttons'] = $this->_getFormButtons($_customer, $this->url . '/ficha');
$this->load->model('lancamento_model', 'lancamentoModel');
$_view['releases'] = $this->lancamentoModel->getCustomerRelease($_customer);
foreach ($_view['releases'] as $i => $value) {
// $_view['releases']['order'][$i] = $this->lancamentoModel->getCustomerOrder($value->id);
$value['order'] = $this->lancamentoModel->getCustomerOrder($value->id);
}
$this->addBreadcrumb('Lançamentos', base_url() . 'lancamentos');
$this->addBreadcrumb('Ficha', base_url() . 'lancamentos/ficha');
$this->addBreadcrumb('Exibir');
$this->extras['css'][] = $this->load->view('lancamentos/consulta/ficha_cliente/form/css', null, true);
$this->extras['scripts'][] = $this->load->view('lancamentos/consulta/ficha_cliente/form/js', $_view, true);
// $pagina = $this->getHtmlPagina('Ficha cliente', $_view);
// $this->load->view('lancamentos/consulta/ficha_cliente/view/view', $pagina);
$this->output->set_content_type('application/json');
$this->output->set_output(json_encode($_view));
}
json result:
{
"release":{
"0":{
"id":"380",
"data_vcto":"2016-01-15",
"data_emissao":"2016-01-15",
"documento":"292\/1",
"vlr":"67.00",
"vlr_divida":"0.00"
},
"order":[
[
{
"id":"142206",
"data_vcto":"2016-01-15 09:59:24",
"vlr_desconto":"0.00",
"vlr_multa":"0.00",
"pago_em":"2018-11-19 09:59:24",
"conta_nome":"Caixa",
"tipo_nome":"Vendas",
"vlr_movimento":"67.00",
"tipo_pagamento_nome":"Dinheiro"
},
{
"id":"213",
"data_vcto":"2016-01-13 09:59:24",
"vlr_desconto":"0.00",
"vlr_multa":"0.00",
"pago_em":"2018-11-19 09:59:24",
"conta_nome":"Caixa",
"tipo_nome":"Vendas",
"vlr_movimento":"22.00",
"tipo_pagamento_nome":"Dinheiro"
}
]
]
}
}
I would like something like that
{
"release":{
"0":{
"id":"380",
"data_vcto":"2016-01-15",
"data_emissao":"2016-01-15",
"documento":"292\/1",
"vlr":"67.00",
"vlr_divida":"0.00",
"order":[
{
"id":"142206",
"data_vcto":"2016-01-15 09:59:24",
"vlr_desconto":"0.00",
"vlr_multa":"0.00",
"pago_em":"2018-11-19 09:59:24",
"conta_nome":"Caixa",
"tipo_nome":"Vendas",
"vlr_movimento":"67.00",
"tipo_pagamento_nome":"Dinheiro"
},
{
"id":"213",
"data_vcto":"2016-01-13 09:59:24",
"vlr_desconto":"0.00",
"vlr_multa":"0.00",
"pago_em":"2018-11-19 09:59:24",
"conta_nome":"Caixa",
"tipo_nome":"Vendas",
"vlr_movimento":"22.00",
"tipo_pagamento_nome":"Dinheiro"
}
]
}
}
}
it is possible ? And what do I have to do in the foreach?
Update: I did as #Yulio Aleman Jimenez suggested...but after that the error appeared
Fatal error: Cannot use object of type stdClass as array in C:\xampp\htdocs\beauty\application\controllers\Lancamentos.php on line 829
Message: Cannot use object of type stdClass as array
Error Print
I think you must change your code like this:
$_releases = $this->lancamentoModel->getCustomerRelease($_customer);
foreach ($_releases as $i => $value) {
// try with this changes
$value = $this->lancamentoModel->getCustomerOrder($value->id);
$_releases[$i] = (object)array_merge((array)$_releases[$i], array('order' => $value));
}
The thing is to store the array of orders in the order of each release.
Update
You have working with objects, it's the reazon you have to cast to array, add new values in order and then cast to object.
This is almost exactly what I want, but that question hasn't been answered and it's been a year. I've managed to get close, I think, but numbers are being printed as keys. In my example it shows up on line 47, but it is repeated for every "course_name" in the actual file.
[
{
"school_name": "Projects",
"terms": [
{
"term_name":"category_name#1",
"departments": [
{
"department_name":"sub_category_name1",
"department_code":"category code text here",
"courses":[
{
"course_name": "project1",
"course_code":"project 1 code text goes here",
"sections":[
{
"section_code":"mike",
"unique_id":"xxx#mail.com"
},
{
"section_code":"dan",
"unique_id":"xxx#gmail.com"
}
]
},
{
"course_name": "project2",
"course_code":"project 2 code text goes here",
"sections":[
{
"section_code":"steve",
"unique_id":"xxx#mail.com"
},
{
"section_code":"chris",
"unique_id":"xxx#gmail.com"
}
]
}
]
},
{
"department_name": "sub_category_name2",
"department_code":"sub category description text goes here..",
"courses": {
-->>> "69": {
"course_name": "project3",
"course_code":"project3 code text goes here ",
"sections":[
{
"section_code":"Alex",
"unique_id":"xxx#gmail.com"
}
]
}
}
}
]
}
]
}
]
Here is the query I am using and an example of data being returned.
SELECT school_name, term_name, department_name, department_code, course_code, course_name, section_code, magento_course_id
FROM schools INNER JOIN term_names ON schools.id=term_names.school_id INNER JOIN departments ON schools.id=departments.school_id INNER JOIN
adoptions ON departments.id=adoptions.department_id
"UCA-2" "SPRING 2013" "ACCOUNTING" "ACCT" "3315" "COST ACCOUNTING" "10258" 10311
What I have is being generated with this code.
$row_array = array();
$terms = array();
$departments = array();
$courses = array();
$h = 0;
$i = 0;
$j = 0;
while ($row = mysqli_fetch_assoc($fetch)) {
$row_array[$row['school_name']]['school_name'] = $row['school_name'];
$akey = array_search($row['term_name'], $terms);
if ($akey === FALSE) {
$m = $h++;
$terms[] = $row['term_name'];
$row_array[$row['school_name']]['terms'][$m]['term_name'] = $row['term_name'];
} else {
$m = $akey;
}
$key = array_search($row['department_code'], $departments);
if ($key === FALSE) {
$k = $i++;
$departments[] = $row['department_code'];
$row_array[$row['school_name']]['terms'][$m]['departments'][$k]['department_name'] = $row['department_name'];
$row_array[$row['school_name']]['terms'][$m]['departments'][$k]['department_code'] = $row['department_code'];
} else {
$k = $key;
}
$skey = array_search($row['course_code'], $courses);
if ($skey === FALSE) {
$l = $j++;
$courses[] = $row['course_code'];
$row_array[$row['school_name']]['terms'][$m]['departments'][$k]['courses'][$l]['course_name'] = $row['course_name'];
$row_array[$row['school_name']]['terms'][$m]['departments'][$k]['courses'][$l]['course_code'] = $row['course_code'];
} else {
$l = $skey;
}
$row_array[$row['school_name']]['terms'][$m]['departments'][$k]['courses'][$l]['sections'][] = array('section_code' => $row['section_code'], 'unique_id' => $row['magento_course_id']);
}
How do I generate this JSON without those numbers showing up?
I think you have some key & encoding problems. Too much key usage, excessive loops in your code. Maybe you should tidy your sql query.
Since you are setting keys for courses, JSON shows it.
Try removing the key after "['courses']" in your last line such as;
Change ['courses'][$l] to ['courses'][]
At the end, encode the array for JSON.
$result = json_encode($result);
My PHP script works fine, but for some element, i get null values whereas in the table the text is well here :
[
{
"etat":"online",
"nb_visiteurs":"0",
"id":"1",
"date_debut":"19\/05\/2014",
"prix":"40",
"description":null,
"id_author":"1",
"titre":null
},
{
"etat":"online",
"nb_visiteurs":"0",
"id":"2",
"date_debut":"21\/05\/2014",
"prix":"30",
"description":null,
"id_author":"1",
"titre":null
},
{
"etat":"offline",
"nb_visiteurs":"0",
"id":"3",
"date_debut":"22\/05\/2014",
"prix":"23",
"description":"TOP NOIR STYLE ASIATIQUE EN BON ETAT T 3\r\n\r\nFAIRE PROPOSITION",
"id_author":"1",
"titre":"Top noir style asiatique en bon etat t3"
},
{
"etat":"online",
"nb_visiteurs":"0",
"id":"4",
"date_debut":"22\/05\/2014",
"prix":"45",
"description":null,
"id_author":"1",
"titre":"Lit+sommier+matelas+ table de chevet+commode"
}
]
Here is the content of my annonces table :
And here is the structure of the table :
<?php
$PARAM_hote='aaaaaa';
$PARAM_port='3306';
$PARAM_nom_bd='bbbbbbbbb';
$PARAM_utilisateur='ccccccccc';
$PARAM_mot_passe='dddddddddd';
// Create connexion to BDD
$connexion = new PDO('mysql:host='.$PARAM_hote.';port='.$PARAM_port.';dbname='.$PARAM_nom_bd, $PARAM_utilisateur, $PARAM_mot_passe);
try {
// Getting username / password
$username = $_POST['username'];
$password = $_POST['password'];
// Prepare SQL request to check if the user is in BDD
$result1=$connexion->prepare("select * from tbl_user where username = '".$username."' AND password = '".$password. "'");
$result1->execute();
// Getting all results in an array
$arrAllUser = $result1->fetchAll(PDO::FETCH_ASSOC);
// If the size of array is equal to 0, there is no user in BDD
if (sizeof($arrAllUser) == 0) {
echo "fail";
}
// In this case, a user has been found, create a JSON object with the user information
else {
// Getting id of the user
$id_user = $arrAllUser[0]['id'];
// Prepare a second SQL request to get all annonces posted by the user
$result2=$connexion->prepare(" select * from annonces where id_author = '".$id_user."' ");
$result2->execute();
// Getting all annonces posted by the user in an array
$arrAllAnnonces = $result2->fetchAll(PDO::FETCH_ASSOC);
// Set in key user the USER structure
$array['user'] = $arrAllUser[0];
// Set in key annonces all annonces from the user
$array['annonces'] = $arrAllAnnonces;
// JSON encore the array
$json_result = json_encode($array);
echo $json_result;
}
} catch(Exception $e) {
echo 'Erreur : '.$e->getMessage().'<br />';
echo 'N° : '.$e->getCode();
}
?>
It's happening because french letters, the function fails to parse them.
try to use flag JSON_UNESCAPED_UNICODE
json_encode($a, JSON_HEX_TAG | JSON_HEX_APOS | JSON_HEX_QUOT | JSON_HEX_AMP | JSON_UNESCAPED_UNICODE)
you can play with the flags
try this
$output = array();
foreach ($array as $row)
{
$output[]=array_map("utf8_encode", $row);
}
$json_result = json_encode($output);
echo $json_result;
agree with volkinc answer,if you have a new php version you can use
json_unescaped_unicode instead of json_encode
and if your php version 5.3 and older unescaped wont work , just add this function at the bottom of the script and use it instead of json_encode
function my_json_encode($in) {
$_escape = function ($str) {
return addcslashes($str, "\v\t\n\r\f\"\\/");
};
$out = "";
if (is_object($in)) {
$class_vars = get_object_vars(($in));
$arr = array();
foreach ($class_vars as $key => $val) {
$arr[$key] = "\"{$_escape($key)}\":\"{$val}\"";
}
$val = implode(',', $arr);
$out .= "{{$val}}";
}elseif (is_array($in)) {
$obj = false;
$arr = array();
foreach($in AS $key => $val) {
if(!is_numeric($key)) {
$obj = true;
}
$arr[$key] = my_json_encode($val);
}
if($obj) {
foreach($arr AS $key => $val) {
$arr[$key] = "\"{$_escape($key)}\":{$val}";
}
$val = implode(',', $arr);
$out .= "{{$val}}";
}else {
$val = implode(',', $arr);
$out .= "[{$val}]";
}
}elseif (is_bool($in)) {
$out .= $in ? 'true' : 'false';
}elseif (is_null($in)) {
$out .= 'null';
}elseif (is_string($in)) {
$out .= "\"{$_escape($in)}\"";
}else {
$out .= $in;
}
return "{$out}";
}
and use my_json_encode instead of json_encode and dont forget this line :
header('content-type:text/html;charset=utf-8');
thanks to the person who made this function i forgot from where i got it.