I have the following array:
$learners=array('Eliza'=87, 'Joe'=81, 'Anne'=69, 'Marley'=39, 'Teddy'=39, 'Jemma'=90, 'Sylvia'=87);
So far I have been able to separate the two arrays as follows:
$tudents=array_keys($learners);
$scores=array_values($learners);
The ranking is as follows:
Student Score Position
Jemma 90 1
Sylvia 87 2
Eliza 87 2
Joe 81 4
Anne 69 5
Marley 39 7
Teddy 69 7
I would like to create a new array with names as keys and positions as values i.e
$positions=array('Jemma'=1, 'Sylvia'=2, 'Eliza'=2, 'Joe'=4, 'Anne'=5, 'Marley'=7, 'Teddy'=7);
This will allow me to echo any name and position at any point on the script. I am not sure how to proceed.
The ranking is not straightforward if the scores have duplicates. If there is a tie at number 2, the 3rd position is skipped. If the tie occurs at the end of the scores, then both scores will be placed at the last position and the preceding position will be skipped, in the example above, position 6 has been skipped and the two 39s occupy position 7.
Any help will be appreciated
// Sort decending
arsort($data);
$vals = array_values($data);
$last = end($vals); // The lowest score
$prev = null;
$rank = 0;
$positions = array();
foreach($data as $student => $score) {
if ($score == $last) {
// The score is the same as the lowest, the rank is set to last position
$rank = count($data);
} else if ($prev != $score) {
// We only update if the score is not the same as prev
$rank++;
} else if ($prev == $score) {
// We matched on the key, replace any items with the
// same score with the current rank
$matches = array_keys($positions, $score);
foreach($matches as $key) {
$positions[$key] = $rank;
}
$positions[$student] = $rank;
// Now skip ahead to the next rank +1
$rank = $rank + count($matches) + 1;
continue;
}
$positions[$student] = $rank;
$prev = $score; // Remember the previous score
}
var_dump($positions);
Here's another solution:
First sort by value (the print_r is just to check progress).
arsort($learners);
print_r($learners);
Then make an array of rankings, but don't advance the rank if the score is the same as the previous element's score.
$rank = $pos = 1;
$prev_score = current($learners);
foreach ($learners as $name => $score) {
if ($score != $prev_score) {
$rank = $pos;
}
$ranking[$name] = $rank;
$prev_score = $score;
$pos++;
}
print_r($ranking);
Now correct the last entries, any element with the same score as the last element should be in 7th place. There's a rarely-used argument to array_keys() that searches for a given value.
$low_score = end($learners);
$last_place = count($learners);
foreach (array_keys($learners, $low_score) as $name) {
$ranking[$name] = $last_place;
}
print_r($ranking);
Output:
Array
(
[Jemma] => 90
[Sylvia] => 87
[Eliza] => 87
[Joe] => 81
[Anne] => 69
[Marley] => 39
[Teddy] => 39
)
Array
(
[Jemma] => 1
[Sylvia] => 2
[Eliza] => 2
[Joe] => 4
[Anne] => 5
[Marley] => 6
[Teddy] => 6
)
Array
(
[Jemma] => 1
[Sylvia] => 2
[Eliza] => 2
[Joe] => 4
[Anne] => 5
[Marley] => 7
[Teddy] => 7
)
Looks like PHP, right?
Basically go through your initial list and stuff them into a new array that uses the names as keys (you're in trouble here if two people have the same name, but I'm assuming this is a homework assignment and that's not an issue?)
$sorted = array();
for ($i=0;$i<count($positions);$i++) {
if (!isset($sorted[$positions[$i]["Student"]])) {
$sorted[$positions[$i]["Student"]] = $positions[$i]["Score"];
} else if ($sorted[$positions[$i]["Student"]]<$positions[$i]["Score"] {
$sorted[$positions[$i]["Student"]] = $positions[$i]["Score"];
}
}
What you're doing here is making an array where the KEY is the name of the student, and putting the first score you find in as the VALUE for that. So $sorted["Jemma"] = 90. Then if you hit that name again, and the score is higher than the current value for $sorted["Jemma"], you're replacing it.
After that, you run an arsort($sorted) to put it in order.
Related
I need to read, line aligns and group by (Cd), which is the only index of each record. Thus, (Cd) refers to each new record, which may contain several sub groups: (11), (22), (Co), etc. These sub groups may contain an additional line (see example of (Co) in the first record, which should concatenate the lines containing "for cabinet" and "for closet.").
My TXT file structure, is this:inventory.txt
>No. 0012 of 01/31/2016
>No. 0012 of 01/31/2016
>(Cd) 12345
>(11) Cod1-023
>(22) 22/12/1945
>(Co) locking doors
>For cabinet
>For closet.
>(Cd) 23456
>(11) Cod1-055
>(21) 01/01/2005
>(22) drawer iron
>,wood
>,aluminum
>(Cd) 78920
>(22) Cod1-077
>(54) 2/22/1975
>(Co) clip Aluminum or iron
>(74) anodized
>(Cd) 0002525
>(Di) Cod4-07100
>(11) 02/22/2017
>(22) shirt Red green
>(54) yellow buttons
>(Co) mango
>,avocado
>,cherry
I implemented the following routine but, after much research and modifications, I was not able to group the sub indices:
Together, I need a routine to transfer the data from the array to variables and, later, to the mysql DB.
If anyone can give me a light, thank you.
$cd = [];
$group = [];
$counter = 0;
$file = fopen ('inventory.txt', 'r');
while (! feof ($file)) {
$row = trim (fgets ($file, 1024));
// $row = trim ($row);
if (substr ($row, 0, 4) == '(cd)') {
$counter = 0;
if (! empty ($group)) {
$cd [$id] = $group;
$group = [];
$counter = 0;
}
$id = substr ($row, 5, strlen ($row) -5);
$cd [$id] [] = $line;
} else {
if (substr ($row, 0, 4)! == '(11)') {
if (isset ($group [$counter-1])) {
$group [$counter -1]. = ''. $line;
$counter--;
}
} else {
$group [] = $row;
}
$counter ++;
}
}
$cd [$id] = $group;
fclose ($file);
echo '<pre>';
print_r ($cd);
exit;
// -------------------------
// routine to transfer data from array to variables
$keys = array_keys ($cd);
for ($i = 0; $i <count ($cd); $i ++) {
echo $keys [$i]. "<br>";
foreach ($cd [$keys [$i]] as $key => $value) {
echo $key. ":". $value. "<br>";
}
echo "<br>";
}
Thank you for editing your question to attach the file content rows. Here is my new solution.
This will disallow concatenation for any lines immediately after a (22) line.
If there are other triggers beyond (22) that should indicate concatenation is unwanted, modify the $concat condition in the second elseif block.
$cd=[]; // declare array
$i=-1; // set outer index
$concat=true;
$file=fopen('inventory.txt','r');
while(!feof($file)){
$row=trim(fgets($file,1024));
if(preg_match('/^\(Cd\)\s(.+)/',$row,$match)){ // capture Cd numbers
++$i; // increment outer_index
$j=-1; // reset inner_index
$id=$match[1]; // store cd value
$concat=true;
}elseif(preg_match('/^(\(..\)\s.*)/',$row,$match)){ // capture Cd data
++$j; // this is a new innerarray element, increment its index
$cd[$i][$id][$j]=$match[1]; // push element into array
$concat=(strpos($match[1],'(22)')!==0?true:false);
}elseif(isset($id) && $concat){ // ignore all file header content
$cd[$i][$id][$j].=" $row"; // concatenate to last element
}
}
echo "<pre>";
var_export($cd); // display in true nested form
echo "</pre>";
foreach($cd as $outer_index=>$cdarrays){
foreach($cdarrays as $id=>$innerarrays){
foreach($innerarrays as $inner_index=>$line){
echo "$outer_index : $id : $inner_index = $line<br>"; // display keys & values by row
}
}
}
The $cd array will have this structure:
array (
0 =>
array (
12345 =>
array (
0 => '(11) Cod1-023',
1 => '(22) 22/12/1945',
2 => '(Co) locking doors For cabinet For closet. ',
),
),
1 =>
array (
23456 =>
array (
0 => '(11) Cod1-055',
1 => '(21) 01/01/2005',
2 => '(22) drawer iron',
),
),
2 =>
array (
78920 =>
array (
0 => '(22) Cod1-077',
1 => '(54) 2/22/1975',
2 => '(Co) clip Aluminum or iron',
3 => '(74) anodized',
),
),
3 =>
array (
'0002525' =>
array (
0 => '(Di) Cod4-07100',
1 => '(11) 02/22/2017',
2 => '(22) shirt Red green',
3 => '(54) yellow buttons',
4 => '(Co) mango ,avocado ,cherry',
),
),
)
Or if you want to view it in a flattened/verbose style:
0 : 12345 : 0 = (11) Cod1-023
0 : 12345 : 1 = (22) 22/12/1945
0 : 12345 : 2 = (Co) locking doors For cabinet For closet.
1 : 23456 : 0 = (11) Cod1-055
1 : 23456 : 1 = (21) 01/01/2005
1 : 23456 : 2 = (22) drawer iron
2 : 78920 : 0 = (22) Cod1-077
2 : 78920 : 1 = (54) 2/22/1975
2 : 78920 : 2 = (Co) clip Aluminum or iron
2 : 78920 : 3 = (74) anodized
3 : 0002525 : 0 = (Di) Cod4-07100
3 : 0002525 : 1 = (11) 02/22/2017
3 : 0002525 : 2 = (22) shirt Red green
3 : 0002525 : 3 = (54) yellow buttons
3 : 0002525 : 4 = (Co) mango ,avocado ,cherry
#mickmackusa I have much to thank for your patience and contribution. His code was excellent, but he was eliminating the lines he was leaping (22). So, I modified the structure to capture the values of those following, including in a new ID inside the array.
My array knowledge is very limited, but the code is functional for my needs.
In case you can contribute to simplify the operation that I built, I'm happy to know.
Why error Occurs "Warning: Undefined offset: 3 and Undefined offset: 5, in this line: $cd[$i][$id][$j]. = "$Row";
$cd=[]; // declare array
$trash=[];
$i=-1; // set outer index
$concat=true;
$file=fopen('inventory.txt','r');
while(!feof($file)){
$row=trim(fgets($file,1024));
if(preg_match('/^\(Cd\)\s(.+)/',$row,$match)){ // capture Cd numbers
++$i; // increment outer_index
$j=-1; // reset inner_index
$id=$match[1]; // store cd value
$concat=true;
$row_previous=false;
$row_ob=false;
}elseif(preg_match('/^(\(..\)\s.*)/',$row,$match)){ // capture Cd data
++$j; // this is a new innerarray element, increment its index
$cd[$i][$id][$j]=$match[1]; // push element into array
//$concat=(strpos($match[1],'(Co)')!==0?true:false);
If (substr($row, 0, 5) == '(Co) ') {
$row_previous=true;
}
}elseif(isset($id)){ // ignore all file header content
If (($row_previous == true)and ($row_ob !== true)){
++$j; //increment its index to insert variable value created for the additional lines
$row="(Ob) ". (trim($row)); //create pre value variable
$row_ob=true;
$cd[$i][$id][$j].="$row "; // concatenate to last element to new
}else{
$cd[$i][$id][$j].=" $row"; // concatenate to last element
}
}
}
echo "<pre>";
var_export($cd); // display in true nested form
echo "</pre>";
foreach($cd as $outer_index=>$cdarrays){
foreach($cdarrays as $id=>$innerarrays){
foreach($innerarrays as $inner_index=>$line){
echo "$outer_index : $id : $inner_index = $line<br>"; // display keys & values by row
}
}
}
I'm about to create "lottary system."
Take a look at my table:
userid-lottaryid-amount
1 -------- 1 ---- 1
2 -------- 1 ---- 10
3 -------- 1 ---- 15
4 -------- 1 ---- 20
I want to choose a winner. and another person for second place.
I just can't select a winner randomly because 4th user has 20 tickets and 1st user has only one.
So I need to generate random results by weight in order to be more fair.
I found php function below but I couldn't figure out how to use it.
function weighted_random_simple($values, $weights){
$count = count($values);
$i = 0;
$n = 0;
$num = mt_rand(0, array_sum($weights));
while($i < $count){
$n += $weights[$i];
if($n >= $num){
break;
}
$i++;
}
return $values[$i];
}
$values = array('1', '10', '20', '100');
$weights = array(1, 10, 20, 100);
echo weighted_random_simple($values, $weights);
I must fetch userid colomn as array to $values and amount colomn to $weights. But I couln't.
Here is my code so far:
$query = $handler->prepare("SELECT
`cvu`.`lottaryid` as `lottaryid`,
`cvu`.`userid` as `userid`,
`cvu`.`amount` as `amount`,
`members`.`id` as `members_memberid`,
`members`.`username` as `username`
FROM `lottariesandmembers` as `cvu`
LEFT JOIN `members` as `members` ON `cvu`.`userid` = `members`.`id` WHERE `cvu`.`lottaryid` = 2");
$query->bindParam(':lottaryid', $lottaryid, PDO::PARAM_INT);
$query->execute();
while($r = $query->fetch()) {
for ( $count=1 ; $count <= $r["amount"] ; $count++ ) {
$abcprint = "$r[userid].$count - $r[username] - <br>";
echo "$abcprint";
}
}
This code I have, only lists users as many times as their amount. For example:
1.1 user1
2.1 user2
2.2 user2
2.3 user2
..
2.10 user2
3.1 user3
..
3.15 user3
4.1 user4
..
4.20 user4
and so on.. But I'm stuck how to pick a winner on that list.
I would like to merge those codes and create this little script, if you would like to help me.
I'm also open for brainstorm if you see the solution on the other way around.
Instead of printing out the values as you are doing, you can just build a large array, and then choose a value randomly from that array.
while($r = $query->fetch()) {
for ( $i=0; $i <= $r["amount"]; $i++ ) {
// Add the user into the array as many times as they have tickets
$tickets[] = $r['userid'];
}
}
// select the first place winner
$first = $tickets[mt_rand(0, count($tickets) - 1)];
// remove the first place winner from the array
$tickets = array_values(array_filter($tickets, function($x) use ($first) {
return $x != $first;
}));
// select the second place winner
$second = $tickets[mt_rand(0, count($tickets) - 1)];
I'm sure there is a more efficient way to do this using math, but I need to think about it a bit more...
This isn't very elegant but should work for smallish lotteries.
It just constructs a massive array and picks an element at random.
Think of having a massive hat full of slips. Each holder gets their stake in 'slips' and each are labelled with their id. i.e. Ten slips with the holder's name 'a', 20 slips with 'b' and so on...
<?php
$holder_totals = array(
'a' => '10',
'b' => '20',
'c' => '20',
'd' => '50'
);
$big_hat = array();
foreach($holder_totals as $holder_id => $total) {
$holder_hat = array_fill(0, intval($total), $holder_id);
$big_hat = array_merge($big_hat, $holder_hat);
}
// Drum roll
foreach (range(1,4) as $n) {
$random_key = array_rand($big_hat);
printf("Winner %d is %s.\n", $n, $big_hat[$random_key]);
unset($big_hat[$random_key]); // Remove winning slip
}
Sample output:
Winner 1 is d.
Winner 2 is c.
Winner 3 is d.
Winner 4 is b.
Big hat looks like this:
Array
(
[0] => a
[1] => a
[2] => a
[3] => a
[4] => a
[5] => a
[6] => a
[7] => a
[8] => a
[9] => a
[10] => b
[11] => b
[12] => b
[13] => b
[14] => b
... and so on...
)
/**
* getRandomWeightedElement()
* Utility function for getting random values with weighting.
* Pass in an associative array, such as array('A'=>5, 'B'=>45, 'C'=>50)
* An array like this means that "A" has a 5% chance of being selected, "B" 45%, and "C" 50%.
* The return value is the array key, A, B, or C in this case. Note that the values assigned
* do not have to be percentages. The values are simply relative to each other. If one value
* weight was 2, and the other weight of 1, the value with the weight of 2 has about a 66%
* chance of being selected. Also note that weights should be integers.
*
* #param array $weightedValues
*/
function getRandomWeightedElement(array $weightedValues) {
$rand = mt_rand(1, (int) array_sum($weightedValues));
foreach ($weightedValues as $key => $value) {
$rand -= $value;
if ($rand <= 0) {
return $key;
}
}
}
Here is an efficient and flexible function. But You have to modify it if you want to use non-integer weighting.
You can use weightedChoice function from my library nspl.
use function \nspl\rnd\weightedChoice;
// building your query here
$pairs = [];
while($r = $query->fetch()) {
$pairs[] = [$r['userid'], $r['amount']];
}
$winnerId = weightedChoice($pairs);
You can install the library with composer:
composer require ihor/nspl
Or you can simply reuse weightedChoice code from GitHub:
/**
* Returns a random element from a non-empty sequence of items with associated weights
*
* #param array $weightPairs List of pairs [[item, weight], ...]
* #return mixed
*/
function weightedChoice(array $weightPairs)
{
if (!$weightPairs) {
throw new \InvalidArgumentException('Weight pairs are empty');
}
$total = array_reduce($weightPairs, function($sum, $v) { return $sum + $v[1]; });
$r = mt_rand(1, $total);
reset($weightPairs);
$acc = current($weightPairs)[1];
while ($acc < $r && next($weightPairs)) {
$acc += current($weightPairs)[1];
}
return current($weightPairs)[0];
}
I have the following array with undefined number of elements
$marks=array('2','4','9','3');
target=50;
I want to randomly loop through the array, add up the values I fetch until the total is my target.
$total=0; /////initialize total
for($i=0;$i<=sizeof($marks);++$i)
{
/////////Pick up random values add them up until $total==$target
/////////return the new array with selected elements that sums up to
/////////target
}
I hope my question is clear, also note that the loop should not iterate too many times since the elements might never add up to the total. I have tried adding the items in line but to no avail. Thanks in advance
I think this'll work for you and always return you value of count to be 50 only
$marks = array(6,7,9,6,7,9,3,4,12,23,4,6,4,5,7,8,4);
$target = 50;
function sum($marks, $target) {
$count = 0;
$result = [];
for ($i = 0; $i <= $target; $i++) {
if ($count < $target) {
$add = $marks[array_rand($marks)];
$count = $count + $add;
$result['add'][] = $add;
} elseif ($count == $target) {
break;
} elseif ($count >= $target) {
$extra = $count - $target;
$count = $count-$extra;
$result['extra'] = $extra;
}
}
return $result;
}
print_r(sum($marks, $target));
The way you describe your logic, a while loop might make more sense:
<?php
$marks = array(2, 4, 9, 3);
$target = 50;
$sum = 0;
$i = 0; // to keep track of which iteration we're on
// PHP can natively randomize an array:
shuffle($marks);
while ($sum < $target && $i < count($marks)) {
$sum += $marks[$i];
$i++; // keep track of which iteration we're on
}
// after the loop, we've either added every number in $marks,
// or $sum >= $target
Don't forget that it might exceed $target without ever being equal to it, as Dagon pointed out in a comment.
Look into PHP's native array shuffle: https://secure.php.net/manual/en/function.shuffle.php
This may be a good alternative for the above answer.
Why I say so is that I have set it in such a way that it doesn't let the total go over the target, and when there is such a situation, the current number in the array is decremented by one and added as a new element so that if there is no possible number in the stack, there will be one eventually making this loop not go on infinitely. :)
<?php
$marks = ['2', '4', '9', '3'];
$target = 50;
$total = 0;
$numbersUsed = [];
while($total != $target) {
$index = rand(0, count($marks) - 1);
$number = $marks[$index];
if($number + $total > $target) {
$number = 0;
$marks[] = $marks[$index] - 1;
} else {
$numbersUsed[] = $number;
}
$total += $number;
echo $total . "\n";
}
// To see which numbers were used:
print_r($numbersUsed);
?>
Testing:
Starting with the array ['2', '4', '9', '3'],
We loop and get the result:
4 13 17 20 22 31 35 44 46 48 48 48 48 50
And we get this array which includes the numbers used to get the final result:
Array
(
[0] => 4
[1] => 9
[2] => 4
[3] => 3
[4] => 2
[5] => 9
[6] => 4
[7] => 9
[8] => 2
[9] => 2
[10] => 2
)
For a website application I need to form random groups of three. The user him/herself cannot grade him/herself (so cannot be part of the group). There will always be a minimum of 4 users.
For example, if there were 5 users, I would have an array as such: Array(0,1,2,3,4) and I would want the output to be (where the key is the user and the data is the group of 3).
Array(
[0 : 1,2,3],
[1 : 0,2,4],
[2 : 1,4,3],
[3 : 0,1,4],
[4 : 0,2,3]
);
Notice the user is never in the group and every user is assigned exactly 3 times.
You cannot simply randomly select users to groups because it might be assigned more than 3 times and force some groups to have less than 3 users in the group.
I hope I explained this problem appropriately and someone will be able to help.
Here is some code that puts three random numbers in a dictionary and works fine for [0,1,2,3] but will (most likely) fail for anything larger because the number will not be equally distributed (and will continue in the while loop forever because there are no possible numbers left).
$rows = range(0,3);
$array_size = count($rows);
$peers_array = Array();
$number_count = array_fill(0, $array_size, 0);
foreach($rows as $index => $row){
$randomNumbers = Array();
for($x = 0; $x < 3; ++$x){
$randomNumber = rand(0, $array_size-1);
while($randomNumber==$index or in_array($randomNumber, $randomNumbers) or $number_count[$randomNumber]>2)
$randomNumber = rand(0, $array_size-1);
$number_count[$randomNumber]++;
$randomNumbers[] = $randomNumber;
}
$peers_array[$index] = $randomNumbers;
}
print_R( $peers_array);
Ok so I've come up with my own solution. It took a little thought but thanks to suggestions I was able to come up with this solution:
First it generates a range from 0 to the number of users - 1 (e.g. for 5 it would give [0,1,2,3,4]) then every time after that it shifts the list one (e.g. [0,1,2,3,4] becomes [4,0,1,2,3]) then it takes each element at a given index of the array and puts it into a group (so if I only wanted groups of 2 it would give 0:[0,4] 1:[0,1] 2:[2,1] and so on...). You then shift the order between the number of users - the size of the group, don't ask just trust me. This guarantees all numbers appear an equal number of times but still randomizes the order.
The lines below accomplishes this:
function getUsers($user_num, $groups_of){
$index_list = range(0,$user_num-1);
$random_indexes = range(0,$user_num-1);
shuffle($random_indexes);
$groups = array();
foreach($index_list as $user_num)
$groups[] = array($random_indexes[$user_num]);
for($i = 0; $i<($groups_of-1); ++$i){
array_unshift($index_list, array_pop($index_list)); //puts the last element first
foreach($index_list as $index => $user_num)
$groups[$index][] = $random_indexes[$user_num];
}
$shift_number = rand(1, ($len_users-$groups_of));
for($i = 0; $i<$shift_number; ++$i)
array_unshift($groups, array_pop($groups));
return $groups
}
I was thinking array_pop would be a good approach, it works well for the first part of the problem, easy to get the current item and make sure it isn't available for the next part, however then you end up having to keep track of too many moving parts.
In the end went for array_diff to remove the current row from the original array.
$rows = range(0,15);
$results = array();
foreach ($rows as $row) {
$others = array_diff($rows,array($row));
shuffle($others);
$results[$row] = array_slice(array_values($others),0,3);
}
var_dump($results);
Results:
array (size=16)
0 =>
array (size=3)
0 => int 9
1 => int 1
2 => int 10
1 =>
array (size=3)
0 => int 10
1 => int 11
2 => int 14
2 =>
array (size=3)
0 => int 3
1 => int 15
2 => int 14
3 =>
array (size=3)
0 => int 9
1 => int 4
2 => int 1
etc...
I think this:(to generalize)
function getUsers($users,$groups_of){
$result = array();
for($i = 0; $i < $users; $i++){
$usernums = array();
while(count($usernums) < $groups_of){
$randomNumber = rand(0, $users-1);
if($i != $randomNumber && !in_array($randomNumber, $usernums)){
$usernums[] = $randomNumber;
}
}
$result[$i] = $usernums;
}
return $result;
}
$users = 5;
$groups_of = 3;
print_r(getUsers($users,$groups_of));
I've got a problem which takes up a lot of time. While it's supposed to be really easy (because it's just so simple!).
My problem:
I have these values inside two arraylists:
$row[0]->COUNTER1 20 10 15
$row[0]->GRADE_POINTS 0 3 5
I am supposed to change these arraylists into this example:
$row[0]->COUNTER1 20 0 0 10 0 15
$row[0]->GRADE_POINTS 0 1 2 3 4 5
So the missing values are supposed to have 0 as the counter.
While this isn't that hard to do it I'm probably over thinking it.
The code which I use to create the first set of numbers is:
$result = new SimpleXMLElement($xmlresult);
$xml = $result->children("soapenv", true)->Body->children();
$xmlBody = $xml[0];
$countPerResultaat = array();
foreach($xmlBody->query[0] as $row)
{
$countPerResultaat[] = (int) $row[0]->COUNTER1;
$xaxis[] = (string) $row[0]->GRADE_POINTS;
}
The code I though that would work is this:
for($i; $i<=10; $i++){
//foreach($xmlBody->query[0] as $row)
//{
$row = $xmlBody->query[0];
if($i==$row[0]->GRADE_POINTS){
$countPerResultaat[] = (int) $row[0]->COUNTER1;
$xaxis[] = (string) $row[0]->GRADE_POINTS;
}else{
$xaxis[] = (string) $i;
$countPerResultaat[] = (int) 0;
}
}
But the row can't be used, I really don't know how to fix this. My only solution would be to use another for-loop, which would create 100 values probably.
Thanks for helping in advance!
If I understand correctly and if $row[0]->COUNTER1 and $row[0]->GRADE_POINTS are arrays. You will just need to loop them and use in_array(). Consider this example:
$counter1 = array(20, 10, 15);
$grade_points = array(0, 3, 5);
$new_grade_points = range(min($grade_points), max($grade_points));
foreach($new_grade_points as $key => &$value) {
// check if its part of the missing index if not get the value,
// if its the missing index put 0
$value = (in_array($key, $grade_points)) ? array_shift($counter1) : 0;
}
$counter1 = array_values($new_grade_points); // now contains 20,0,0,10,0,15
$grade_points = array_keys($new_grade_points); // now contains 0,1,2,3,4,5
print_r($counter1);
Sample Output:
Array
(
[0] => 20
[1] => 0
[2] => 0
[3] => 10
[4] => 0
[5] => 15
)
I think you want to count the amount of times a grade has been given? You should just loop through as usual, and when there is no value you should/could define it as 0. After that just count how many duplicates you have in the array. That way the key of the $xaxis is the grade, and the value is the amount of times that grade has been given.
foreach($xmlBody->query[0] as $row)
{
$counter = (int) $row[0]->COUNTER1;
if(counter) $countPerResultaat[] = $counter;
else $countPerResultaat[] = 0;
}
$xaxis = array_count_values($counter);