Counting rows/records in a multidimensional array - php

I have a set of nested arrays.
[data] is the top level array.
The lower level arrays are all identified by incremental numbers, dynamically assigned...essentially each sub-array identifies a row/record of information.
How would I extract the count of the sub-arrays? I need to be able to do this to post this data into a DB.
The number of sub-arrays is dynamic, and can change depending on what data I am parsing through.
[data] => Array
(
[0] => Array
(
[id] => 3475
[name] => Player1
[score] => 11870
[rank] => 213
[total_cities] => 2
[crown] => None
[alliance_id] => 134
[title] => Earl
[fame_total] => 509875
[fame_rank] => 381
[defeated_total] => 3436
[defeated_rank] => 376
[plunder_total] => 1388754
[plunder_rank] => 245
)
[1] => Array
(
[id] => 3523
[name] => Player2
[score] => 1978
[rank] => 281
[total_cities] => 1
[crown] => None
[alliance_id] => 134
[title] => Baron
[fame_total] => 0
[fame_rank] => 448
[defeated_total] => 0
[defeated_rank] => 448
[plunder_total] => 0
[plunder_rank] => 436
)
[2] => Array
(
[id] => 73
[name] => Player3
[score] => 1308
[rank] => 304
[total_cities] => 1
[crown] => None
[alliance_id] => 134
[title] => Marquess
[fame_total] => 5604153
[fame_rank] => 237
[defeated_total] => 37270
[defeated_rank] => 229
[plunder_total] => 68130
[plunder_rank] => 335
)

I used a combination of the methods highlighted by Marc B and Thanos to get my desired result
This is the code I used:
$count = 0;
foreach($data as $data=>$inner_array){
$count = $count+1;
}
echo $count;
I ran it with a test data set with 143 unique rows, and I got that echo back, so life is good.
Thanks guys.

Simplest method:
$count = 0;
foreach($mainarray as $subarray)
$count += count($subarray);
}

Let's assume $data is your main array:
This one prints the name of each inner array (0, 1, 2... for your example) and then counts each sub-array items:
echo "Number of sub-arrays: ".count($online_time); //optional
foreach($data as $inner_array=>$data_of_inner_array) {
echo $inner_array;
echo " --- ".count($data_of_inner_array);
echo "<br/>";
}
i assume output will be
Number of sub-arrays: 3
0 --- 14
1 --- 14
2 --- 14

Related

PHP - Add a new element into each multidimensional array

I have an array that looks like this:
Array
(
[0] => stdClass Object
(
[quiz_id] => 1033
[quiz_venue] => 6
[quiz_host] => 46
[quiz_golden_question] => 100
[quiz_golden_question_outcome] => 0
[quiz_running] => 1
[quiz_status] => 100
[quiz_trainee] => 0
)
[1] => stdClass Object
(
[quiz_id] => 985
[quiz_venue] => 57
[quiz_host] => 21
[quiz_golden_question] => 0
[quiz_golden_question_outcome] => 0
[quiz_running] => 1
[quiz_status] => 310
[quiz_trainee] => 0
)
I want to go through each array, and insert a new value (quiz_venue_name), this is what I have;
$quizzes = $wpdb->get_results( $prepared );
foreach ($quizzes as $quiz => $item) {
$venuetitle = get_the_title($item->quiz_venue);
$quizzes['quiz_venue_name'] = $venuetitle;
}
return $quizzes;
However, all it does is add the new values to the very end of the multidimensional array as new arrays - rather than adding them into each!
I feel like I'm doing something obvious wrong, so any help is much appreciated!
The end result I need would be;
Array
(
[0] => stdClass Object
(
[quiz_id] => 1033
[quiz_venue] => 6
[quiz_host] => 46
[quiz_golden_question] => 100
[quiz_golden_question_outcome] => 0
[quiz_running] => 1
[quiz_status] => 100
[quiz_trainee] => 0
[quiz_venue_name] => NEW VALUE
)
[1] => stdClass Object
(
[quiz_id] => 985
[quiz_venue] => 57
[quiz_host] => 21
[quiz_golden_question] => 0
[quiz_golden_question_outcome] => 0
[quiz_running] => 1
[quiz_status] => 310
[quiz_trainee] => 0
[quiz_venue_name] => NEW VALUE
)
Your $quizzes variable is an array of objects (Instance of stdClass), so you should use it attribute to set value in each iteration ($item->quiz_venue_name instead of $quizzes['quiz_venue_name']):
...
foreach ($quizzes as $quiz => $item) {
$venuetitle = get_the_title($item->quiz_venue);
$item->quiz_venue_name = $venuetitle;
}
...
In fact the $quizzes['quiz_venue_name']=... code will be set a value for index quiz_venue_name in root of $quizzes array.

How can I loop my array to total the score percentage based on his correct answer?

I have this response
[0] => Array (
[name] => Test
[question_id] => 4
[question_choice_id] => 14
[choice_level] => 0
)
[1] => Array (
[name] => Test
[question_id] => 5
[question_choice_id] => 19
[choice_level] => 0
)
[2] => Array (
[name] => Test
[question_id] => 6
[question_choice_id] => 24
[choice_level] => 0
)
[3] => Array (
[name] => Test
[question_id] => 7
[question_choice_id] => 26
[choice_level] => 0
)
[4] => Array (
[name] => Test
[question_id] => 8
[question_choice_id] => 29
[choice_level] => 1
)
[5] => Array (
[name] => Test
[question_id] => 9
[question_choice_id] => 36
[choice_level] => 0
)
[6] => Array (
[name] => Test
[question_id] => 1
[question_choice_id] => 2
[choice_level] => 0
)
[7] => Array (
[name] => Test
[question_id] => 2
[question_choice_id] => 7
[choice_level] => 0
)
[8] => Array (
[name] => Test
[question_id] => 3
[question_choice_id] => 9
[choice_level] => 0
)
I want to get the percentage of the user with the formula of
Score = the_right_answer / total_count_array * 100
The correct answer has a value of 1 in the choice_level columns
so for my example is, the formula should be
Score = 1/ 9 * 100
How can I get the total from this array?
Once I get the answer I just like to return them to my view.
public function progress(){
$category_id = Session::get('category_id');
$user_set_id = Session::get('user_set_id');
$score = Answer::get_user_score($user_set_id,$category_id);
return view('pages.user.user_progress', [
'name' => '',
'score' => '',
]);
}
Can anyone help me on how to do this properly? any help would be really appreciated.
Based on Score = total count_of_array / the_right_answer * 100:
for total count_of_array could be calculated easily using count($answes)
for calculating the_right_answer, you can use array_map() or manual loop:
$total = count($answers);
$correct = 0;
foreach($answers as $answer){
if($answer['choice_level'] == '1'){
$correct++;
}
}
the snippet above will give you $correct as total correct answer
Now that you have the needed data, you can then do the calculation yourself. However, I would remind you that when the user doesn't have any correct answer, you will face a Division by zero warning. Keep that in mind😉
Since apparently choice_level can only take the values 0 or 1 you can use array_sum to get the number of correct answers. You will need to reduce the response array to just that field first, you can achive that with array_column. So all together:
$score = array_sum(array_column($answers, 'choice_level')) / count($answers) * 100;
for each($arrayname['score'] as $item){
}

Using values in one associative array to test against values in another associative array

I need help, tried for days without successs, new to PHP so please forgive me, I have an associative Array below returned from a database table grading system, what I want to achieve is try "scores" from another associative array, iterate through the grading system until I find a score that falls between values in a row in the grading system then return the letter grade and remarks, see below what have tried, am exhausted, any help would be very appreciated.
code I have tried
while ($row = $grade->fetch(PDO::FETCH_ASSOC)) {
$data = $row;
var_export($data);
} //fetches the grading system whose array is seen below
while($row = $stmt->fetch(PDO::FETCH_ASSOC)){
$scores = $row;
var_export($scores);
}// fetches scores of students in test
foreach($data as $key=> $grading) {
foreach($scores as $key =>$values){
if($values["marks"]>=$grading["grade_min"] && $values["marks"]<=$grading["grade_max"])
print_r($values["marks"]);
print_r($grading["grade"]);
print_r($grading["remarks"]);
}
} Am trying to iterate each scores against the grading system but not successful, please help.
Array
(
[0] => Array
(
[id] => 2
[grade_min] => 1
[grade_max] => 39
[grade] => E
[remarks] => Fail
)
[1] => Array
(
[id] => 3
[grade_min] => 40
[grade_max] => 49
[grade] => D
[remarks] => Pass
)
[2] => Array
(
[id] => 4
[grade_min] => 50
[grade_max] => 59
[grade] => C
[remarks] => Credit
)
[3] => Array
(
[id] => 5
[grade_min] => 60
[grade_max] => 69
[grade] => B
[remarks] => Good
)
[4] => Array
(
[id] => 6
[grade_min] => 70
[grade_max] => 79
[grade] => A
[remarks] => Very Good
)
[5] => Array
(
[id] => 7
[grade_min] => 80
[grade_max] => 100
[grade] => A+
[remarks] => Excellent
)
)
Array
(
[0] => Array
(
[id] => 2
[grade_min] => 1
[grade_max] => 39
[grade] => E
[remarks] => Fail
)
[1] => Array
(
[id] => 3
[grade_min] => 40
[grade_max] => 49
[grade] => D
[remarks] => Pass
)
[2] => Array
(
[id] => 4
[grade_min] => 50
[grade_max] => 59
[grade] => C
[remarks] => Credit
)
[3] => Array
(
[id] => 5
[grade_min] => 60
[grade_max] => 69
[grade] => B
[remarks] => Good
)
[4] => Array
(
[id] => 6
[grade_min] => 70
[grade_max] => 79
[grade] => A
[remarks] => Very Good
)
[5] => Array
(
[id] => 7
[grade_min] => 80
[grade_max] => 100
[grade] => A+
[remarks] => Excellent
)
)
Scores Array looks like this:
Array
(
[0] => 35
[1] => 48
[2] => 57
[3] => 78
[4] => 75
[5] => 89
)
I want to iterate these scores array against the grading system array and return only the "grade" and "remarks" that matched where the scores is between "grade_min" and "grade_max"
It's better to iterate over scores and then iterate grading to find the one that score belongs to.
Additionally, your if has no curly braces, so it will execute only the first sentence after it.
// fetches the grading system whose array is seen below
while ($row = $grade->fetch(PDO::FETCH_ASSOC)) {
$data = $row;
// var_export($data); // No need to se this anymore
}
// fetches scores of students in test
while($row = $stmt->fetch(PDO::FETCH_ASSOC)){
$scores = $row;
// var_export($scores); // No need to see this anymore
}
// Iterate scores first (I don't know if you need the index or not)
foreach($scores as $scoreIndex => $score) {
// Search grading for this score (Index not needed here, just values)
foreach($data as $grading) {
if($score['marks'] >= $grading['grade_min'] && $score['marks'] <= $grading['grade_max']) {
// Score is inside this grading
// Echo, print or assign what you need here
// Then exit the loop for grading
break;
}
}
}
Based on your output for $scores, that array is just a single value, no associative array, so the loop should be:
// Iterate scores first (I don't know if you need the index or not)
foreach($scores as $scoreIndex => $score) {
// Search grading for this score (Index not needed here, just values)
foreach($data as $grading) {
// $score is an integer, not an array
if($score >= $grading['grade_min'] && $score <= $grading['grade_max']) {
// Score is inside this grading
// Echo here what you need
// Then exit the loop for grading
break;
}
}
}

how to remove array value from array when value not same from both the value [duplicate]

This question already has answers here:
How to Remove value from an array using another array with multiple values?
(4 answers)
Closed 4 years ago.
I have two array, and i want to remove duplicate record from array2. i don't want to link_id 35 record in array 2 because link_id 35 record is present in array1 so it's not show in array2.
I tried with array_map and Unique methods but it's not working well because i think both the array doesn't have the same value.
$array1=
[0] => stdClass Object
(
[link_id] => 35
[link_name] => Test Listerine cool mint packets 3 pack
[alias] => aa
[link_desc] =>
[user_id] => 47
[link_hits] => 103
[link_votes] => 1
[link_rating] => 5.000000
[link_featured] => 0
[link_published] => 1
[link_approved] => 1
[link_template] =>
)
[1] => stdClass Object
(
[link_id] => 373
[link_name] => Test Subject Data Collection Fish Fresh Yellow Tail
[alias] => ba
[link_desc] =>
[user_id] => 47
[link_hits] => 198
[link_votes] => 8
[link_rating] => 2.875000
[link_featured] => 0
[link_published] => 1
[link_approved] => 1
[link_template] =>
)
$array2 =
[0] => stdClass Object
(
[link_id] => 35
[link_name] => Test Listerine cool mint packets 3 pack
[link_desc] =>
[lat] => 0.000000
[lng] => 0.000000
[contactperson] =>
[cat_name] => AA - Made in USA
[link_votes] => 1
[link_rating] => 5.000000
[link_featured] => 0
[value] => 30020864
)
[1] => stdClass Object
(
[link_id] => 541
[link_name] => Test Subject Data Collection Fish Fresh Yellow Tail
[link_desc] =>
[lat] => 25.182573
[lng] => -80.093079
[country] => United States
[postcode] => 33431
[contactperson] => Captain Jack Certified Charters
[cat_name] => BA - Product of USA
[link_votes] => 8
[link_rating] => 2.875000
[link_featured] => 0
[value] => NA
)
You can do that with array-filter. First extract all the ids from the first array and then filter the second array based of those ids.
$arr1 = array( (object) ["link_id"=> 35, "key" => "AAA"], (object) ["link_id"=> 373, "key" => "BBB"]);
$arr2 = array( (object) ["link_id"=> 35, "key" => "CCC"], (object) ["link_id"=> 341, "key" => "DDD"]);
$ids = array_column($arr1, "link_id");
$arr2 = array_filter($arr2, function ($e) use ($ids) {
return !in_array($e->link_id, $ids); //keep him in arr2 only if NOT in ids of arr1
});
Updated more fast answer Consider big amount of data (as for #mickmackusa comment) use this:
$ids = [];
foreach($arr1 as $e)
$ids[$e->link_id] = true;
$arr2 = array_filter($arr2, function ($e) use ($ids) {
return !isset($ids[$e->link_id]);
});
First solution is in O(n^2) and the second is in O(n)
This should do in php7.
Untested code:
var_export(array_diff_key(array_column($array2, null, 'link_id'), array_column($array1, null, 'link_id'));
Assign new 1st level keys to both arrays, then filter on those keys.
Checking against keys will be more efficient than making iterated calls of in_array.

Count multidimensional array keys with specific value

I've got an array and I need count the keys with a specific value, which is proving to be a nightmare.
Array([0] => Array
(
[0] => 1
[ruleid] => 1
[1] => Test Outbound Life 1
[rule_name] => Test Outbound Life 1
[2] => Life Insurance
[product_type] => Life Insurance
[3] => 1
[status] => 1
[4] => 1000
[priority] => 1000
[5] => 100
[quantity] => 100
[6] => 1-2-3-4-5-6-7-
[dayofweek] => 1-2-3-4-5-6-7-
[7] => 2
[income] => 2
[8] => external/arc.php
[integrationfile] => external/arc.php
[9] => 1
[partnerid] => 1
)
[1] => Array
(
[0] => 2
[ruleid] => 2
[1] => Test Outbound Life 2
[rule_name] => Test Outbound Life 2
[2] => Life Insurance
[product_type] => Life Insurance
[3] => 1
[status] => 1
[4] => 800
[priority] => 800
[5] => 100
[quantity] => 100
[6] => 1-2-3-4-5-6-7-
[dayofweek] => 1-2-3-4-5-6-7-
[7] => 2
[income] => 2
[8] => test.php
[integrationfile] => test.php
[9] => 1
[partnerid] => 1
) )
The array will be generated dynamically so the same array will appear in the array.
I want to count how many times the same ruleid appears is it will look like this:
Array{
[1] => 1
[2] => 1
}
Update: I need to count how many times ruleid = 2 or how many times ruleid = 1
So you want to count the number of time each ruleid appears inside an array.
Let's call this array $count. This is how I'd do it.
$count = array();
foreach($arrays as $array) { // $arrays is your big ass array containing arrays
// increment the value with the key corresponding to ruleid (improved by JustOnUnderMillions)
$count[$array['ruleid']] = isset($count[$array['ruleid']]) ? ($count[$array['ruleid']] + 1) : 1;
}
print_r(count); // should give you what you're looking for
I have worked it out by looping and counting how many times a ruleid appears in an array.
foreach ($count as $key => $value) {
$c = 0;
//check that outbound has passed all rules
foreach ($out as $k => $v) {
if ($v['ruleid']==$key) {
$c +=1;
}
}
if ($c==$value) {
//add valid outbound to array
foreach ($out as $k => $v) {
if ($v['ruleid']==$key) {
$valid[$key] = $v;
}
}
}
}
The loop checks the ruleid has passed all rules I had already counted in the $count variable.

Categories