i am facing problem with some logical error - php

I want to sum the individual student number with some condition. The Condition is if a student fails any one subject then it will give me 0 value not sum any of his number. When used this condition it will give me wrong value.now these the problem I faced and I tried lots of things but not working. In the below, I give you code and the output and also the output I want.
controller:
if (!empty($examSchedule)) {
$new_array = array();
foreach ($studentList as $stu_key => $stu_value) {
$array = array();
$array['student_id'] = $stu_value['id'];
$array['admission_no'] = $stu_value['admission_no'];
$array['roll_no'] = $stu_value['roll_no'];
$array['firstname'] = $stu_value['firstname'];
$array['lastname'] = $stu_value['lastname'];
$array['dob'] = $stu_value['dob'];
$array['father_name'] = $stu_value['father_name'];
$x = array();
foreach ($examSchedule as $ex_key => $ex_value) {
$exam_array = array();
$exam_array['exam_schedule_id'] = $ex_value['id'];
$exam_array['exam_id'] = $ex_value['exam_id'];
$exam_array['subject_id'] = $ex_value['subject_id'];
$exam_array['full_marks'] = $ex_value['full_marks'];
$exam_array['passing_marks'] = $ex_value['passing_marks'];
$exam_array['exam_name'] = $ex_value['name'];
$exam_array['exam_type'] = $ex_value['type'];
$student_exam_result = $this->examresult_model->get_exam_result($ex_value['id'], $stu_value['id']);
$exam_array['attendence'] = $student_exam_result->attendence;
$exam_array['get_marks'] = $student_exam_result->get_marks;
$x[] = $exam_array;
}
$array['exam_array'] = $x;
$new_array[] = $array;
}
$data['examSchedule'] = $new_array;
}
if ($this->input->post('save_exam') == "save_exam") {
$ex_array = array();
$exam_id = $this->input->post('exam_id');
$student_array = $this->input->post('student');
$exam_array = $this->input->post('exam_schedule');
$total_marks = array();
foreach ($student_array as $key => $student) {
foreach ($examSchedule as $ex_key => $ex_value) {
foreach ($exam_array as $key => $exam) {
$record['get_marks'] = 0;
$record['attendence'] = "pre";
if ($this->input->post('student_absent' . $student . "_" . $exam) == "") {
$get_marks = $this->input->post('student_number' . $student . "_" . $exam);
$record['get_marks'] = $get_marks;
$passing_marks = $ex_value['passing_marks'];
if ($get_marks != '0' && $get_marks>=$passing_marks) {
$total_marks[$student] += $get_marks;
} else {
$total_marks[$student] = 0;
break;
}
} else {
$record['attendence'] = $this->input->post('student_absent' . $student . "_" . $exam);
}
$record['exam_schedule_id'] = $exam;
$record['student_id'] = $student;
$record['exam_id'] = $exam_id;
$inserted_id = $this->examresult_model->add_exam_result($record);
if ($inserted_id) {
$ex_array[$student] = $exam_id;
}
}
$total['total_mark'] = $total_marks[$student];
$total['exam_id'] = $this->input->post('exam_id');
$total['student_id'] = $student;
$total['class_id'] = $class_id;
$total['section_id'] = $section_id;
$total['year'] = date("Y");
$total_mark = $this->examresult_model->add_total_result($total);
}
echo "<pre>";
print_r( $total['total_mark']);
}
exit();
if (!empty($ex_array)) {
$this->mailsmsconf->mailsms('exam_result', $ex_array, NULL, $exam_array);
}
redirect('admin/mark');
}
output(i get):
3213
3171
1248
2989
4291
0
0
0
0
0
0
0
0
output(i want):
459
453
416
0 //(427 is the sum but one subject fail thatswhy it sum zero)
613
0
0
0
0
0
0
0
0
value of student_array (these all are student id):
Array(
[0] => 110
[1] => 111
[2] => 120
[3] => 121
[4] => 112
[5] => 113
[6] => 114
[7] => 122
[8] => 115
[9] => 116
[10] => 117
[11] => 118
[12] => 119
)
value of exam_array:
Array
(
[0] => 84
[1] => 85
[2] => 86
[3] => 87
[4] => 88
[5] => 89
[6] => 90
)
value of examSchedule:
Array
(
[0] => Array
(
[student_id] => 110
[admission_no] => 01
[roll_no] => 01
[firstname] => Md. Abdur
[lastname] => Rahaman
[dob] => 2015-05-12
[father_name] => Sowpan Chow
[exam_array] => Array
(
[0] => Array
(
[exam_schedule_id] => 84
[exam_id] => 7
[subject_id] => 4
[full_marks] => 100
[passing_marks] => 33
[exam_name] => Bangla
[exam_type] => Theory
[attendence] => pre
[get_marks] => 75.00
)
[1] => Array
(
[exam_schedule_id] => 85
[exam_id] => 7
[subject_id] => 1
[full_marks] => 100
[passing_marks] => 33
[exam_name] => English
[exam_type] => Theory
[attendence] => pre
[get_marks] => 82.00
)
[2] => Array
(
[exam_schedule_id] => 86
[exam_id] => 7
[subject_id] => 2
[full_marks] => 100
[passing_marks] => 33
[exam_name] => Math
[exam_type] => Theory
[attendence] => pre
[get_marks] => 88.00
)
[3] => Array
(
[exam_schedule_id] => 87
[exam_id] => 7
[subject_id] => 3
[full_marks] => 100
[passing_marks] => 33
[exam_name] => Religion
[exam_type] => Theory
[attendence] => pre
[get_marks] => 87.00
)
[4] => Array
(
[exam_schedule_id] => 88
[exam_id] => 7
[subject_id] => 10
[full_marks] => 50
[passing_marks] => 16
[exam_name] => Art & Craft
[exam_type] => Theory
[attendence] => pre
[get_marks] => 45.00
)
[5] => Array
(
[exam_schedule_id] => 89
[exam_id] => 7
[subject_id] => 9
[full_marks] => 50
[passing_marks] => 16
[exam_name] => General Knowledge
[exam_type] => Theory
[attendence] => pre
[get_marks] => 42.00
)
[6] => Array
(
[exam_schedule_id] => 90
[exam_id] => 7
[subject_id] => 11
[full_marks] => 50
[passing_marks] => 16
[exam_name] => Computer
[exam_type] => Theory
[attendence] => pre
[get_marks] => 40.00
)
)
)
[1] => Array
(
#value
)
[2] => Array
(
#value
)
[3] => Array
(
#value
)
[4] => Array
(
#value
)
[5] => Array
(
#value
)..
[12] => Array
(
#value
)

you could make a separate foreach loop to get the whole marks of a single student, then check if it contains any 0 mark on it before doing a passing mark validation/additions :
if ($this->input->post('save_exam') == "save_exam") {
$ex_array = array();
$exam_id = $this->input->post('exam_id');
$student_array = $this->input->post('student');
$exam_array = $this->input->post('exam_schedule');
$total_marks = array();
foreach ($student_array as $key => $student) {
// check if current student having 0 mark
$student_mark = [];
foreach ($exam_array as $key => $exam) {
$student_mark[$student][] = $this->input->post('student_number' . $student . "_" . $exam);
}
$zero_mark_flag = in_array(0, $student_mark[$student], true) ? true : false; // return true if contains 0 mark
foreach ($examSchedule as $ex_key => $ex_value) {
foreach ($exam_array as $key => $exam) {
$record['get_marks'] = 0;
$record['attendence'] = "pre";
if ($this->input->post('student_absent' . $student . "_" . $exam) == "") {
$get_marks = $this->input->post('student_number' . $student . "_" . $exam);
$record['get_marks'] = $get_marks;
$passing_marks = $ex_value['passing_marks'];
// there are 0 on one or more student marks, so skip the mark addition
if ($zero_mark_flag === true) {
$total_marks[$student] = 0;
break;
} else if ($get_marks != '0' && $get_marks>=$passing_marks) {
$total_marks[$student] += $get_marks;
}
} else {
$record['attendence'] = $this->input->post('student_absent' . $student . "_" . $exam);
}
$record['exam_schedule_id'] = $exam;
$record['student_id'] = $student;
$record['exam_id'] = $exam_id;
$inserted_id = $this->examresult_model->add_exam_result($record);
if ($inserted_id) {
$ex_array[$student] = $exam_id;
}
}
$total['total_mark'] = $total_marks[$student];
$total['exam_id'] = $this->input->post('exam_id');
$total['student_id'] = $student;
$total['class_id'] = $class_id;
$total['section_id'] = $section_id;
$total['year'] = date("Y");
$total_mark = $this->examresult_model->add_total_result($total);
}
echo "<pre>";
print_r( $total['total_mark']);
}
exit();
if (!empty($ex_array)) {
$this->mailsmsconf->mailsms('exam_result', $ex_array, NULL, $exam_array);
}
redirect('admin/mark');
}
So the student mark will always set to 0.

Related

Grouping data in ChartJS and PHP

Hi have a data table which i am trying to draw a graph of using ChartJS. The data array looks like below
Array
(
[0] => Array
(
[Sort] => 2
[Weeks] => 1-2 Weeks
[Severity] => P1
[Count] => 7
)
[1] => Array
(
[Sort] => 2
[Weeks] => 1-2 Weeks
[Severity] => P2
[Count] => 3
)
[2] => Array
(
[Sort] => 2
[Weeks] => 1-2 Weeks
[Severity] => P3
[Count] => 4
)
[3] => Array
(
[Sort] => 2
[Weeks] => 1-2 Weeks
[Severity] => P4
[Count] => 3
)
[4] => Array
(
[Sort] => 3
[Weeks] => 2-3 weeks
[Severity] => P1
[Count] => 1
)
[5] => Array
(
[Sort] => 4
[Weeks] => >4 weeks
[Severity] => No Value
[Count] => 1
)
[6] => Array
(
[Sort] => 4
[Weeks] => >4 weeks
[Severity] => P1
[Count] => 1
)
[7] => Array
(
[Sort] => 4
[Weeks] => >4 weeks
[Severity] => P3
[Count] => 1
)
)
I converted that array compatible with ChartJS like below
Array
(
[labels] => Array
(
[0] => >4 weeks
[1] => 2-3 weeks
[2] => 1-2 Weeks
)
[datasets] => Array
(
[0] => Array
(
[label] => No Value
[backgroundColor] => #F00
[borderColor] => #F00
[borderWidth] => 1
[maxBarThickness] => 50
[data] => Array
(
[0] => 1
)
)
[1] => Array
(
[label] => P1
[backgroundColor] => #84a4d4
[borderColor] => #84a4d4
[borderWidth] => 1
[maxBarThickness] => 50
[data] => Array
(
[0] => 1
[1] => 1
[2] => 7
)
)
[2] => Array
(
[label] => P3
[backgroundColor] => #eb8d22
[borderColor] => #eb8d22
[borderWidth] => 1
[maxBarThickness] => 50
[data] => Array
(
[0] => 1
[1] => 4
)
)
[3] => Array
(
[label] => P2
[backgroundColor] => #FBCEB1
[borderColor] => #FBCEB1
[borderWidth] => 1
[maxBarThickness] => 50
[data] => Array
(
[0] => 3
)
)
[4] => Array
(
[label] => P4
[backgroundColor] => #7FFFD4
[borderColor] => #7FFFD4
[borderWidth] => 1
[maxBarThickness] => 50
[data] => Array
(
[0] => 3
)
)
)
)
But the data gets scrambled when it is plotted to Chart. The data gets arranged like this
This is the real data and how the graph should look like
Here is my code
function chart(){
$ar= RNCPHP\AnalyticsReport::fetch('Open tickets Ageing by priority');
$arr= $ar->run(0, $filters);
$chartInit = array();
$chartArr['data'] = array();
// push the report data into an array
for ( $ii = $arr->count(); $ii--; ) {
$row = $arr->next();
if($row['Severity'] == null || $row['Severity'] == "") {
$row['Severity'] = "No Value";
}
$row['Sort'] = $row['Sort'];
array_push($chartInit, $row);
}
echo "<pre>";
print_r($chartInit);
array_multisort(array_map(function($element) {
return $element['Sort'];
}, $chartInit), SORT_DESC, $chartInit);
$chartDataArr = array();
$sevArr = array();
foreach($chartInit as $k => $v) {
if(!isset($chartDataArr[$v['Weeks']])) {
$chartDataArr[$v['Weeks']] = array();
}
array_push($chartDataArr[$v['Weeks']], $v);
if(!in_array($v['Severity'], $sevArr)) {
array_push($sevArr, $v['Severity']);
}
}
$mapLabels = array();
$parsedAry = array();
$parsedAry['labels'] = array();
$parsedAry['datasets'] = array();
for($i = 0; $i < count($sevArr); $i++) {
$parsedAry['datasets'][$i] = array();
$parsedAry['datasets'][$i]['label'] = $sevArr[$i];
$parsedAry['datasets'][$i]['backgroundColor'] = $this->getColor($i);
$parsedAry['datasets'][$i]['borderColor'] = $this->getColor($i);
$parsedAry['datasets'][$i]['borderWidth'] = 1;
$parsedAry['datasets'][$i]['maxBarThickness'] = 50;
$parsedAry['datasets'][$i]['data'] = array();
}
foreach($chartDataArr as $k => $v) {
array_push($parsedAry['labels'], $k);
foreach($v as $k1 => $v1) {
$keySev = "";
foreach($parsedAry['datasets'] as $k2 => $v2) {
if($v2['label'] == $v1['Severity']) {
$keySev = $k2;
}
}
if($v1['Count'] == null || $v1['Count'] == "") {
$v1['Count'] = 0;
}
array_push($parsedAry['datasets'][$keySev]['data'], $v1['Count']);
}
}
echo "<pre>";
print_r($parsedAry);
echo "</pre>";
$chartArr['data'] = $parsedAry;
return $chartArr;
}
In my view page i'm displaying data with ChartJS Function
<canvas id="chart6"></canvas>
<script>
var ctx = document.getElementById('chart6').getContext('2d');
var data = <?php echo $data ?>;
var drawChart = new Chart(ctx, {
type: 'bar',
data: data,
options: {
scales: {
yAxes: [{
ticks: {
beginAtZero: true,
stepSize: 1
}
}]
},
title: {
display: true,
text: 'Open tickets Ageing by priority'
}
}
});
</script>
Please Help.
Your code has several problems.
First, your datasets should has data in numbers of labels so you can't ignore empty places without filling them. To fix this problem you need to change
$parsedAry['datasets'][$i]['data'] = array(); to $parsedAry['datasets'][$i]['data'] = array(0, 0, 0, 0, 0);
This will add 5 empty spot in your datasets.
Second you have to put numbers in right places for this one you have to add a counter for your last loop to identify right places.
Finally your code should look like this.
function chart()
{
$ar = RNCPHP\AnalyticsReport::fetch('Open tickets Ageing by priority');
$arr = $ar->run(0, $filters);
$chartInit = array();
$chartArr['data'] = array();
// push the report data into an array
for ($ii = $arr->count(); $ii--;) {
$row = $arr->next();
if ($row['Severity'] == null || $row['Severity'] == "") {
$row['Severity'] = "No Value";
}
$row['Sort'] = $row['Sort'];
array_push($chartInit, $row);
}
echo "<pre>";
print_r($chartInit);
array_multisort(array_map(function ($element) {
return $element['Sort'];
}, $chartInit), SORT_DESC, $chartInit);
$chartDataArr = array();
$sevArr = array();
foreach ($chartInit as $k => $v) {
if (!isset($chartDataArr[$v['Weeks']])) {
$chartDataArr[$v['Weeks']] = array();
}
array_push($chartDataArr[$v['Weeks']], $v);
if (!in_array($v['Severity'], $sevArr)) {
array_push($sevArr, $v['Severity']);
}
}
$mapLabels = array();
$parsedAry = array();
$parsedAry['labels'] = array();
$parsedAry['datasets'] = array();
for ($i = 0; $i < count($sevArr); $i++) {
$parsedAry['datasets'][$i] = array();
$parsedAry['datasets'][$i]['label'] = $sevArr[$i];
$parsedAry['datasets'][$i]['backgroundColor'] = $this->getColor($i);
$parsedAry['datasets'][$i]['borderColor'] = $this->getColor($i);
$parsedAry['datasets'][$i]['borderWidth'] = 1;
$parsedAry['datasets'][$i]['maxBarThickness'] = 50;
$parsedAry['datasets'][$i]['data'] = array(0, 0, 0, 0, 0);
}
$labelsNo = 0;
foreach ($chartDataArr as $k => $v) {
array_push($parsedAry['labels'], $k);
foreach ($v as $k1 => $v1) {
$keySev = "";
foreach ($parsedAry['datasets'] as $k2 => $v2) {
if ($v2['label'] == $v1['Severity']) {
$keySev = $k2;
}
}
if ($v1['Count'] == null || $v1['Count'] == "") {
$v1['Count'] = 0;
}
$parsedAry['datasets'][$keySev]['data'][$labelsNo] = $v1['Count'];
}
$labelsNo++;
}
echo "<pre>";
print_r($parsedAry);
echo "</pre>";
$chartArr['data'] = $parsedAry;
return $chartArr;
}

combine and add data in one array index?

i have a array :
Array
(
[0] => Array
(
[spid] => 20
[name] => Sunny
[clientid] => 15
[selectedproduct] => ["190","191"]
[memberid] => 637
[partner_id] => 390
[monthly_forecast] => a:2:{i:0;s:151:"[["1","0","0","1","0","0","1","0","1","0","0","0"],["1","0","0","0","1","0","0","0","1","0","1","1"],["1","0","1","0","1","0","1","0","1","0","0","1"]]";i:1;s:151:"[["1","0","1","0","1","0","1","0","1","0","1","0"],["1","0","1","0","1","1","0","1","0","1","0","1"],["1","0","1","0","1","0","1","1","1","0","1","1"]]";}
[growth_plan] => {"product":["190","191"],"plans":["8","8"]}
[other_palns] => {"product":["190","191"],"plans":["8","8"],"total":["4000","5000"]}
[marketing_s_values] => {"190":"2400","191":"7200"}
[marketing_s_values_monthly] => {"190":[{"1":"150","2":"150","3":"150","4":"150","5":"150","6":"150","7":"150","8":"150","9":"150","10":"150","11":"150","12":"150"},{"1":"200","2":"200","3":"200","4":"200","5":"200","6":"200","7":"200","8":"200","9":"200","10":"200","11":"200","12":"200"},{"1":"250","2":"250","3":"250","4":"250","5":"250","6":"250","7":"250","8":"250","9":"250","10":"250","11":"250","12":"250"},{"1":"300","2":"300","3":"300","4":"300","5":"300","6":"300","7":"300","8":"300","9":"300","10":"300","11":"300","12":"300"},{"1":"350","2":"350","3":"350","4":"350","5":"350","6":"350","7":"350","8":"350","9":"350","10":"350","11":"350","12":"350"}],"191":[{"1":"500","2":"500","3":"500","4":"500","5":"500","6":"500","7":"500","8":"500","9":"500","10":"500","11":"500","12":"500"},{"1":"600","2":"600","3":"600","4":"600","5":"600","6":"600","7":"600","8":"600","9":"600","10":"600","11":"600","12":"600"},{"1":"700","2":"700","3":"700","4":"700","5":"700","6":"700","7":"700","8":"700","9":"700","10":"700","11":"700","12":"700"},{"1":"800","2":"800","3":"800","4":"800","5":"800","6":"800","7":"800","8":"800","9":"800","10":"800","11":"800","12":"800"},{"1":"900","2":"900","3":"900","4":"900","5":"900","6":"900","7":"900","8":"900","9":"900","10":"900","11":"900","12":"900"}]}
)
[1] => Array
(
[spid] => 20
[name] => Sunny
[clientid] => 15
[selectedproduct] => ["199","210"]
[memberid] => 641
[partner_id] => 394
[monthly_forecast] => a:2:{i:0;s:163:"[["10","0","0","0","30","0","0","60","0","0","0","0"],["20","0","0","30","0","0","20","0","0","0","50","0"],["30","0","0","0","20","0","0","30","0","20","0","30"]]";i:1;s:154:"[["20","0","0","0","0","0","0","0","0","0","0","0"],["30","0","0","0","0","0","0","0","0","0","0","0"],["40","0","0","0","0","0","0","0","0","0","0","0"]]";}
[growth_plan] => {"product":["199","210"],"plans":["8","8"]}
[other_palns] => {"product":["199","210"],"plans":["10","10"],"total":["6000","3000"]}
[marketing_s_values] => {"199":"4700","210":"0"}
[marketing_s_values_monthly] => {"199":[{"1":"4600","2":"0","3":"0","4":"0","5":"0","6":"0","7":"0","8":"0","9":"0","10":"0","11":"0","12":"0"},{"1":"4700","2":"0","3":"0","4":"0","5":"0","6":"0","7":"0","8":"0","9":"0","10":"0","11":"0","12":"0"},{"1":"4800","2":"0","3":"0","4":"0","5":"0","6":"0","7":"0","8":"0","9":"0","10":"0","11":"0","12":"0"},{"1":"4900","2":"0","3":"0","4":"0","5":"0","6":"0","7":"0","8":"0","9":"0","10":"0","11":"0","12":"0"},{"1":"5000","2":"0","3":"0","4":"0","5":"0","6":"0","7":"0","8":"0","9":"0","10":"0","11":"0","12":"0"}],"210":[{"1":"0","2":"0","3":"0","4":"0","5":"0","6":"0","7":"0","8":"0","9":"0","10":"0","11":"0","12":"0"},{"1":"0","2":"0","3":"0","4":"0","5":"0","6":"0","7":"0","8":"0","9":"0","10":"0","11":"0","12":"0"},{"1":"0","2":"0","3":"0","4":"0","5":"0","6":"0","7":"0","8":"0","9":"0","10":"0","11":"0","12":"0"},{"1":"0","2":"0","3":"0","4":"0","5":"0","6":"0","7":"0","8":"0","9":"0","10":"0","11":"0","12":"0"},{"1":"0","2":"0","3":"0","4":"0","5":"0","6":"0","7":"0","8":"0","9":"0","10":"0","11":"0","12":"0"}]}
)
[2] => Array
(
[spid] => 20
[name] => Sunny
[clientid] => 15
[selectedproduct] => ["190","191","192","193"]
[memberid] => 574
[partner_id] => 374
[monthly_forecast] => a:4:{i:0;s:151:"[["1","0","0","1","0","0","1","0","1","0","0","0"],["1","0","0","0","1","0","0","0","1","0","1","1"],["1","0","1","0","1","0","1","0","1","0","0","1"]]";i:1;s:151:"[["1","0","1","0","1","0","1","0","1","0","1","0"],["1","0","1","0","1","1","0","1","0","1","0","1"],["1","0","1","0","1","0","1","1","1","0","1","1"]]";i:2;s:151:"[["1","1","1","0","1","1","1","0","0","0","1","1"],["1","1","1","0","0","1","1","1","1","0","1","1"],["1","1","1","1","0","0","1","1","1","1","1","1"]]";i:3;s:151:"[["1","0","1","0","0","0","1","0","1","0","0","2"],["1","0","0","2","1","0","1","0","1","1","0","1"],["1","0","2","1","1","1","0","1","0","1","1","1"]]";}
[growth_plan] => {"product":["190","191","192","193"],"plans":["8","8","9","8"]}
[other_palns] => {"product":["190","191","192","193"],"plans":["8","8","8","8"],"total":["4000","5000","1500","36000"]}
[marketing_s_values] => {"190":"2400","191":"7200","192":"2400","193":"24000"}
[marketing_s_values_monthly] => {"190":[{"1":"150","2":"150","3":"150","4":"150","5":"150","6":"150","7":"150","8":"150","9":"150","10":"150","11":"150","12":"150"},{"1":"200","2":"200","3":"200","4":"200","5":"200","6":"200","7":"200","8":"200","9":"200","10":"200","11":"200","12":"200"},{"1":"250","2":"250","3":"250","4":"250","5":"250","6":"250","7":"250","8":"250","9":"250","10":"250","11":"250","12":"250"},{"1":"300","2":"300","3":"300","4":"300","5":"300","6":"300","7":"300","8":"300","9":"300","10":"300","11":"300","12":"300"},{"1":"350","2":"350","3":"350","4":"350","5":"350","6":"350","7":"350","8":"350","9":"350","10":"350","11":"350","12":"350"}],"191":[{"1":"500","2":"500","3":"500","4":"500","5":"500","6":"500","7":"500","8":"500","9":"500","10":"500","11":"500","12":"500"},{"1":"600","2":"600","3":"600","4":"600","5":"600","6":"600","7":"600","8":"600","9":"600","10":"600","11":"600","12":"600"},{"1":"700","2":"700","3":"700","4":"700","5":"700","6":"700","7":"700","8":"700","9":"700","10":"700","11":"700","12":"700"},{"1":"800","2":"800","3":"800","4":"800","5":"800","6":"800","7":"800","8":"800","9":"800","10":"800","11":"800","12":"800"},{"1":"900","2":"900","3":"900","4":"900","5":"900","6":"900","7":"900","8":"900","9":"900","10":"900","11":"900","12":"900"}],"192":[{"1":"100","2":"100","3":"100","4":"100","5":"100","6":"100","7":"100","8":"100","9":"100","10":"100","11":"100","12":"100"},{"1":"200","2":"200","3":"200","4":"200","5":"200","6":"200","7":"200","8":"200","9":"200","10":"200","11":"200","12":"200"},{"1":"300","2":"300","3":"300","4":"300","5":"300","6":"300","7":"300","8":"300","9":"300","10":"300","11":"300","12":"300"},{"1":"400","2":"400","3":"400","4":"400","5":"400","6":"400","7":"400","8":"400","9":"400","10":"400","11":"400","12":"400"},{"1":"500","2":"500","3":"500","4":"500","5":"500","6":"500","7":"500","8":"500","9":"500","10":"500","11":"500","12":"500"}],"193":[{"1":"1500","2":"1500","3":"1500","4":"1500","5":"1500","6":"1500","7":"1500","8":"1500","9":"1500","10":"1500","11":"1500","12":"1500"},{"1":"2000","2":"2000","3":"2000","4":"2000","5":"2000","6":"2000","7":"2000","8":"2000","9":"2000","10":"2000","11":"2000","12":"2000"},{"1":"2200","2":"2200","3":"2200","4":"2200","5":"2200","6":"2200","7":"2200","8":"2200","9":"2200","10":"2200","11":"2200","12":"2200"},{"1":"2500","2":"2500","3":"2500","4":"2500","5":"2500","6":"2500","7":"2500","8":"2500","9":"2500","10":"2500","11":"2500","12":"2500"},{"1":"2700","2":"2700","3":"2700","4":"2700","5":"2700","6":"2700","7":"2700","8":"2700","9":"2700","10":"2700","11":"2700","12":"2700"}]}
)
In this array as you see "spid" is similar to in all the array index.i just want that it will merge all the data in one index array.
As you see "selectedproduct" of index 0 and index 2 is similar data like 190 and 191 whenever the "selectedproduct" is similar i just want that there respective "monthly_forecast" values added with each other and merge all the three index values into one but only in the case where there "selectedproduct" is similar only those "monthly_forecast" value added.
i tried this code:
$new_values = array();
foreach($get_partner_same_forecast as $value) {
if(isset($new_values[$value['spid']])) {
$temp = $new_values[$value['spid']];
$temp['selectedproduct'] .= ',' . $value['selectedproduct'];
$user[] = json_decode($value['selectedproduct'],true);
$result = array();
foreach($user as $item) {
$result = array_merge($result, $item);
}
$temp['selectedproduct']=json_encode($result);
$temp['partner_acc_name'] .= ',' . $value['partner_acc_name'];//mergepartner name
$temp['crm_acc_name'] .= ',' . $value['crm_acc_name']; //merge crmname
$temp['memberid'] .= ',' . $value['memberid'];//merge memberid
$temp['partner_id'] .= ',' . $value['partner_id'];//merge partnerid
$temp['growth_plan'] .= ',' . $value['growth_plan'];//merge growth plan
$user1[] = json_decode($value['growth_plan'],true);
$product = array();
$plan = array();
foreach($user1 as $k=>$v)
{
$product = array_merge($product, $v['product']);
$plan = array_merge($plan, $v['plans']);
$user1[$k]['product'] = $product;
$user1[$k]['plans'] = $plan;
}
$temp['growth_plan']=json_encode($user1[1]);
$temp['monthly_forecast'] .= ',' . $value['monthly_forecast'];//merge unserialize monthly data
$data1=array();
$data2=array();
$data2=unserialize($value['monthly_forecast']);
$data1=unserialize($temp['monthly_forecast']);
$combinedData=array();
$combinedData = array($data1, $data2);
$monthly_forecast = array();
$monthly_forecast=serialize($combinedData);
$temp['monthly_forecast']=$monthly_forecast;//merge monthly
$monthly_forecast=unserialize($monthly_forecast);
//echo "<pre>"; print_r($monthly_forecast);echo "</pre>";
$new_values[$value['spid']] = $temp;
} else {
$new_values[$value['spid']] = $value;
}
}
$new_values = array_values($new_values);

Perfect Ranking with ties using PHP alone

In my attempt to find the perfect ranking solution with ties, I was stuck at giving the correct ranking. Codes will explain what I am trying to achieve better:
I have the following array:
$standings = array(
'player_1' => 30,
'player_2' => 26,
'player_3' => 28,
'player_9' => 28
);
Now in order to rank it with ties, I have the following function:
function setRanking($standings) {
$rankings = array();
arsort($standings);
$rank = 1;
$tie_rank = 0;
$prev_score = -1;
foreach ($standings as $name => $score) {
if ($score != $prev_score) { //this score is not a tie
$count = 0;
$prev_score = $score;
$rankings[$name] = array('score' => $score, 'rank' => $rank);
} else { //this score is a tie
$prev_score = $score;
if ($count++ == 0) {
$tie_rank = $rank - 1;
}
$rankings[$name] = array('score' => $score, 'rank' => $tie_rank);
}
$rank++;
}
return $rankings;
}
echo '<pre>';
print_r(setRanking($standings));
Output:
Array
(
[player_1] => Array
(
[score] => 30
[rank] => 1
)
[player_3] => Array
(
[score] => 28
[rank] => 2
)
[player_9] => Array
(
[score] => 28
[rank] => 2
)
[player_2] => Array
(
[score] => 26
[rank] => 4
)
)
Expected Output:
Array
(
[player_1] => Array
(
[score] => 30
[rank] => 1
)
[player_3] => Array
(
[score] => 28
[rank] => 2
)
[player_9] => Array
(
[score] => 28
[rank] => 2
)
[player_2] => Array
(
[score] => 26
[rank] => 3
)
)
The problem is it prints the ranking as 1,2,2,4 whereas it should print 1,2,2,3 according to my assumption. So how can it print 1,2,2,3? Where could thing possibly go wrong? Any help is appreciated. Thanks.
Just change your else block, You are not decrements your $rank value so its hold the same value as it is. You just do the $rank - 1 cause its just less 1 to store in a variable not change the main value.
foreach ($standings as $name => $score) {
if ($score != $prev_score) { //this score is not a tie
$count = 0;
$prev_score = $score;
$rankings[$name] = array('score' => $score, 'rank' => $rank);
} else { //this score is a tie
$prev_score = $score;
$rank--; // Decrements here
if ($count++ == 0) {
$tie_rank = $rank;
}
$rankings[$name] = array('score' => $score, 'rank' => $tie_rank);
}
$rank++;
}
return $rankings;

How to group keys and values of an (sub)array and sum its values using PHP? [duplicate]

This question already has answers here:
Group array data on one column and sum data from another column
(5 answers)
Closed 9 months ago.
I have the following array
Array (
[0] => Array
(
[0] => ALFA
[1] => 213
)
[1] => Array
(
[0] => ALFA
[1] => 151
)
[2] => Array
(
[0] => ALFA
[1] => 197
)
[3] => Array
(
[0] => BETA
[1] => 167
)
[4] => Array
(
[0] => ZETA
[1] => 254
)
[5] => Array
(
[0] => GAMA
[1] => 138
)
[6] => Array
(
[0] => GAMA
[1] => 213
)
)
And I would like to group the key[0] of the subarray so I can see how many equal keys it has.
Something like that:
ALFA => 3
BETA => 1
EPSI => 1
GAMA => 2
I tried with array_count_values, but without success.
foreach ($array as $value) {
echo '<pre>';
print_r(array_count_values($value));
echo '</pre>';
}
With that we have following result:
Array
(
[ALFA] => 1
[213] => 1
)
Array
(
[ALFA] => 1
[151] => 1
)
...
Array
(
[GAMA] => 1
[213] => 1
)
And after that I would like to sum the values of each group as well.
ALFA => 213 + 151 + 197
BETA => 167
ZETA => 254
GAMA => 138 + 213
I think that when we solve the first part of the problem, the second would follow easier with quite the same method.
The final purpose is to divide the sum of values by the number of occurrences of each key group, so we can have an average of the values just like that:
ALFA => (213+151+197) / 3 = 187
BETA => 167
ZETA => 254
GAMA => (138+213) / 2 = 175,5
This is not the main problem, but as I said, I'm stuck with the beginning of the solution and would appreciate any help.
I'm surprised at all the long and complicated answers. However, the initial foreach to model your data to something manageable is needed. After that you just need to do a really simple array_walk.
<?php
$result = array();
foreach ($array as $el) {
if (!array_key_exists($el[0], $result)) {
$result[$el[0]] = array();
}
$result[$el[0]][] = $el[1];
}
array_walk($result, create_function('&$v,$k', '$v = array_sum($v) / count($v);'));
?>
Result:
Array
(
[ALFA] => 187
[BETA] => 167
[ZETA] => 254
[GAMA] => 175.5
)
Solution for you is here:
Code:
$input = [
['alfa', 123],
['alfa', 223],
['alfa', 122],
['alfa', 554],
['alfa', 34],
['dalfa', 123],
['halfa', 223],
['dalfa', 122],
['halfa', 554],
['ralfa', 34]
];
$result = [];
foreach ($input as $node) {
if (isset($result[$node[0]])) {
$result[$node[0]] = ['sum' => $result[$node[0]]['sum'] + $node[1], 'count' => $result[$node[0]]['count'] + 1];
} else {
$result[$node[0]] = ['sum' => $node[1], 'count' => 1];
}
}
print_r($result);
foreach ($result as $key => &$data) {
$data = $data['sum'] / $data['count'];
}
print_r($result);
Output:
Array
(
[alfa] => Array
(
[sum] => 1056
[count] => 5
)
[dalfa] => Array
(
[sum] => 245
[count] => 2
)
[halfa] => Array
(
[sum] => 777
[count] => 2
)
[ralfa] => Array
(
[sum] => 34
[count] => 1
)
)
Array
(
[alfa] => 211.2
[dalfa] => 122.5
[halfa] => 388.5
[ralfa] => 34
)
$sort = array();
foreach ($array as $value) {
$sort[$value[0]][] = $value[1];
}
then you count how many keys each has
$keys = array();
foreach($sort as $k => $v) {
$keys[$k] = count($v);
}
then for calculating the amount
$sum = array();
$average = array();
foreach($sort as $k => $v) {
$amount = 0;
foreach($v as $val) {
$amount += $val;
}
$sum[$k] = $amount;
$average[$k] = $amount / $keys[$k];
}
HOWEVER, If you want all the details in one array:
$final = array();
foreach ($array as $value) {
$final[$value[0]]["values"][] = $value[1];
}
foreach($final as $k => $v) {
$final[$k]["amount"] = count($v['values']);
$amount = 0;
foreach($v['values'] as $val) {
$amount += $val;
}
$final[$k]["sum"] = $amount;
$final[$k]["average"] = $amount / $final[$k]["amount"];
}
example: http://jdl-enterprises.co.uk/sof/25789697.php
Includes Output
Just copy the codes to your favorite text editor, sure it works perfectly.
$items = [
['ALFA',213],
['ALFA',151],
['ALFA',197],
['BETA',167],
['ZETA',254],
['GAMA',138],
['GAMA',213]
];
echo '<pre>' . print_r($items,true) . '</pre>';
$result;
foreach ($items as $value) {
# code...
if (isset($result[$value[0]])) {
$sum = $result[$value[0]]['sum'] + $value[1];
$count = $result[$value[0]]['count'] + 1;
$result[$value[0]] = ['sum' => $sum , 'count' => $count, 'divided' => ($sum / $count)];
} else {
$result[$value[0]] = ['sum' => $value[1] , 'count' => 1 , 'divided' => ($value[1] / 1) ];
}
}
echo '<pre>' . print_r($result,true) . '</pre>';
$myArray = [
["ALFA",213],
["ALFA",151],
["ALFA",197],
["BETA",167],
["ZETA",254],
["GAMA",138],
["GAMA",213]
];
$a1 = array(); //TEMPORARY ARRAY FOR KEEPING COUNT & TOTAL VALUES
$res = array(); //ARRAY USED TO KEEP RESULT
foreach($myArray as $val)
{
//AVOID PESKY NOTICES FOR UNDEFINED INDEXES
if ( !array_key_exists($val[0],$a1) ) {
$a1[$val[0]] = array("count" => 0,"total" => 0);
$res[$val[0]] = 0;
}
//INCREMENT THE COUNT OF INSTANCES OF THIS KEY
$a1[$val[0]]["count"]++;
//INCREMENT THE TOTAL VALUE OF INSTANCES OF THIS KEY
$a1[$val[0]]["total"]+=$val[1];
// UPDATE RESULT ARRAY
$res[$val[0]] = $a1[$val[0]]["total"] / $a1[$val[0]]["count"];
}
print_r($res);
Should result in:
Array
(
[ALFA] => 187
[BETA] => 167
[ZETA] => 254
[GAMA] => 175.5
)
Sample: http://phpfiddle.org/lite/code/a7nt-5svf

PHP foreach() last value not being compared

I have an array of values as such:
Array
(
[0] => Array
(
[product_colour_sizes_id] => 37105
[product_colour_sizes_product_id] => 810
[product_colour_sizes_option_value_colour_id] => 61
[product_colour_sizes_option_value_size_id] => 904
[quantity] => 999
[product_colour_sizes_name_sizes] => 16-165
[product_colour_sizes_name_colours] => Red
)
[1] => Array
(
[product_colour_sizes_id] => 37104
[product_colour_sizes_product_id] => 810
[product_colour_sizes_option_value_colour_id] => 61
[product_colour_sizes_option_value_size_id] => 905
[quantity] => 999
[product_colour_sizes_name_sizes] => 17-175
[product_colour_sizes_name_colours] => Red
)
[2] => Array
(
[product_colour_sizes_id] => 37103
[product_colour_sizes_product_id] => 810
[product_colour_sizes_option_value_colour_id] => 61
[product_colour_sizes_option_value_size_id] => 906
[quantity] => 999
[product_colour_sizes_name_sizes] => 185-19
[product_colour_sizes_name_colours] => Red
)
[3] => Array
(
[product_colour_sizes_id] => 37102
[product_colour_sizes_product_id] => 810
[product_colour_sizes_option_value_colour_id] => 61
[product_colour_sizes_option_value_size_id] => 907
[quantity] => 999
[product_colour_sizes_name_sizes] => 19.5
[product_colour_sizes_name_colours] => Red
)
)
I then have a foreach loop which iterates over the above data and reduces each array down to a single row corresponding to different [product_colour_sizes_name_sizes]. However i have a problem that the last array is not being compared. Here is my loop:
foreach($product_combinations as $key => $product_combination){
if($key > -1){
if($product_combinations[$key+1]['product_colour_sizes_name_colours']
== $product_combinations[$key]['product_colour_sizes_name_colours']
){
$color = $product_combinations[$key]['product_colour_sizes_name_colours'];
$color['name'] = $color;
$id = $product_combinations[$key]['product_colour_sizes_option_value_size_id'];
$sizes[$id] = $product_combinations[$key]['product_colour_sizes_name_sizes'];
$quantity = $product_combinations[$key]['quantity'];
$sizes['quantity'] = $quantity;
/* Dont forget theses*/
$sizes['product_colour_sizes_id'] = $product_combination['product_colour_sizes_id'];
$sizes['product_colour_sizes_product_id'] = $product_combination['product_colour_sizes_product_id'];
$sizes['product_colour_sizes_option_value_colour_id'] = $product_combination['product_colour_sizes_option_value_colour_id'];
$sizes["product_colour_sizes_option_value_size_id$x"] =$product_combination['product_colour_sizes_option_value_size_id'];
$x++;
} else {
array_push($colours,
array(
$color => $sizes
));
unset($sizes);
$x = 0;
}
}
}
Essentially now, my 4th ([3]) array is being compared as
$product_combinations[$key+1] == $product_combinations[$key]['product_colour_sizes_name_colours'] with $key+1 being an empty value.
I know the issue as stated above, but can't think of a good way to overcome it with my current logic, can anyone think of a solution?
Edit
What i am attempting to do is reduce the row down to this exact array structure (with the last array included of course that is currently not be added):
Array
(
[0] => Array
(
[Red] => Array
(
[904] => 16-165
[quantity] => 999
[product_colour_sizes_id] => 37103
[product_colour_sizes_product_id] => 810
[product_colour_sizes_option_value_colour_id] => 61
[product_colour_sizes_option_value_size_id0] => 904
[905] => 17-175
[product_colour_sizes_option_value_size_id1] => 905
[906] => 185-19
[product_colour_sizes_option_value_size_id2] => 906
)
)
)
A bit unclear on your original core logic, but based on your example output data, I believe the solution below should work.
The key is really understanding your final desired output because a lot of the logical loops the original code goes through can be eliminated by just using the magic of associative arrays. This solves the whole $key+1 matching $key issue—which would never get the last value due to the inherent flaw in $key+1 logic—as well as a few other things.
Anyway, here is an array of test values including extra values for a Blue color in addition to the Red; cleaned up code to follow:
// Test data array.
$product_combinations = array();
$product_combinations[0][product_colour_sizes_id] = 37105;
$product_combinations[0][product_colour_sizes_product_id] = 810;
$product_combinations[0][product_colour_sizes_option_value_colour_id] = 61;
$product_combinations[0][product_colour_sizes_option_value_size_id] = 904;
$product_combinations[0][quantity] = 999;
$product_combinations[0][product_colour_sizes_name_sizes] = '16-165';
$product_combinations[0][product_colour_sizes_name_colours] = 'Red';
$product_combinations[1][product_colour_sizes_id] = 37104;
$product_combinations[1][product_colour_sizes_product_id] = 810;
$product_combinations[1][product_colour_sizes_option_value_colour_id] = 61;
$product_combinations[1][product_colour_sizes_option_value_size_id] = 905;
$product_combinations[1][quantity] = 999;
$product_combinations[1][product_colour_sizes_name_sizes] = '17-175';
$product_combinations[1][product_colour_sizes_name_colours] = 'Red';
$product_combinations[2][product_colour_sizes_id] = 37103;
$product_combinations[2][product_colour_sizes_product_id] = 810;
$product_combinations[2][product_colour_sizes_option_value_colour_id] = 61;
$product_combinations[2][product_colour_sizes_option_value_size_id] = 906;
$product_combinations[2][quantity] = 999;
$product_combinations[2][product_colour_sizes_name_sizes] = '185-19';
$product_combinations[2][product_colour_sizes_name_colours] = 'Red';
$product_combinations[3][product_colour_sizes_id] = 37102;
$product_combinations[3][product_colour_sizes_product_id] = 810;
$product_combinations[3][product_colour_sizes_option_value_colour_id] = 61;
$product_combinations[3][product_colour_sizes_option_value_size_id] = 907;
$product_combinations[3][quantity] = 999;
$product_combinations[3][product_colour_sizes_name_sizes] = '19.5';
$product_combinations[3][product_colour_sizes_name_colours] = 'Red';
$product_combinations[4][product_colour_sizes_id] = 37102;
$product_combinations[4][product_colour_sizes_product_id] = 810;
$product_combinations[4][product_colour_sizes_option_value_colour_id] = 61;
$product_combinations[4][product_colour_sizes_option_value_size_id] = 907;
$product_combinations[4][quantity] = 999;
$product_combinations[4][product_colour_sizes_name_sizes] = '19.5';
$product_combinations[4][product_colour_sizes_name_colours] = 'Blue';
$product_combinations[5][product_colour_sizes_id] = 37103;
$product_combinations[5][product_colour_sizes_product_id] = 810;
$product_combinations[5][product_colour_sizes_option_value_colour_id] = 61;
$product_combinations[5][product_colour_sizes_option_value_size_id] = 906;
$product_combinations[5][quantity] = 999;
$product_combinations[5][product_colour_sizes_name_sizes] = '185-19';
$product_combinations[5][product_colour_sizes_name_colours] = 'Blue';
And here is the reworked code logic based on the original poster’s code & desired output:
// Init the colours array.
$colours = array();
// Init the sizes array.
$sizes = array();
// Init the increment array.
$increment = array();
// Main logic.
foreach ($product_combinations as $key => $product_combination){
// Set the color & id.
$color = $product_combinations[$key]['product_colour_sizes_name_colours'];
$id = $product_combinations[$key]['product_colour_sizes_option_value_size_id'];
// Set the sizes array data.
$sizes[$color][$id] = $product_combinations[$key]['product_colour_sizes_name_sizes'];
$sizes[$color]['quantity'] = $product_combinations[$key]['quantity'];
$sizes[$color]['product_colour_sizes_id'] = $product_combination['product_colour_sizes_id'];
$sizes[$color]['product_colour_sizes_product_id'] = $product_combination['product_colour_sizes_product_id'];
$sizes[$color]['product_colour_sizes_option_value_colour_id'] = $product_combination['product_colour_sizes_option_value_colour_id'];
$sizes[$color]['product_colour_sizes_option_value_size_id' . $increment[$color]] = $product_combination['product_colour_sizes_option_value_size_id'];
$increment[$color]++;
// Now place the colours array in the sizes array.
$colours[$color] = $sizes[$color];
} // foreach
And the output of that would be:
Array
(
[Red] => Array
(
[904] => 16-165
[quantity] => 999
[product_colour_sizes_id] => 37102
[product_colour_sizes_product_id] => 810
[product_colour_sizes_option_value_colour_id] => 61
[product_colour_sizes_option_value_size_id] => 904
[905] => 17-175
[product_colour_sizes_option_value_size_id1] => 905
[906] => 185-19
[product_colour_sizes_option_value_size_id2] => 906
[907] => 19.5
[product_colour_sizes_option_value_size_id3] => 907
)
[Blue] => Array
(
[907] => 19.5
[quantity] => 999
[product_colour_sizes_id] => 37103
[product_colour_sizes_product_id] => 810
[product_colour_sizes_option_value_colour_id] => 61
[product_colour_sizes_option_value_size_id] => 907
[906] => 185-19
[product_colour_sizes_option_value_size_id1] => 906
)
)

Categories