I ran an election that has a variable number of winners for each category. (One category can have 3 winners, another 1 winner, another 2 winners, etc.)
Currently I am displaying the results like this:
foreach($newarray as $key => $value){
echo $key . $value . “<br>”;
}
This returns
Barack Obama 100
Mitt Romney 100
John Smith 94
Jane Smith 85
What I need to do is have it echo out something if two of the values are the same based on that predetermined number. So, if the predetermined number was one, it would show this:
Barack Obama 100 tie
Mitt Romney 100 tie
John Smith 94
Jane Smith 85
If the predetermined number was two, it would show this since the second and third values aren’t the same:
Barack Obama 100 winner
Mitt Romney 100 winner
John Smith 94
Jane Smith 85
Thank you for your time.
$max = max($array);
$tie = count(array_keys($array,$max)) > $predeterminedNumber;
foreach($newarray as $key => $value){
echo $key . $value . ($value==$max ? ($tie ? ' tie' :' winner') : ''). '<br>';
}
Allthough it becomes a bit more complex if you need the 3 winners don't necessarily have the same score:
$predefinedNumber = whatever;
arsort($array);
//first $predefinedNumber are either winners or tied.
$winners = array_slice($array,0,$predefinedNumber,true);
//the next entry determines whether we have ties
$next = array_slice($array,$predefinedNumber,1,true);
//active tie on entries with this value
$nextvalue = reset($next);
//the above 2 statements would be equivalent to (take your pick):
//$values = array_values($array);
//$nextvalue = $values[$predefinedNumber];
foreach($array as $key => $value){
echo $key.' '.$value;
if($value == $nextvalue){
echo ' tie';
} else if(isset($winners[$key])){
echo ' winner';
}
echo '<br>';
}
Related
Hi I have a PHP array like this
$table=array();
$subject_names=array();
$subject_names[118]="English";
$subject_names[108]="Software Engeneering";
$table['Josh'][118]['int'] =55;
$table['Josh'][118]['ext'] = 10;
$table['Josh'][108]['int'] =45;
$table['Josh'][108]['ext'] = 12;
$table['Matt'][118]['int'] =45;
$table['Matt'][118]['ext'] = 12;
$table['Matt'][108]['int'] =50;
$table['Matt'][108]['ext'] = 15;
Here 118 and 108 are subject_id I am trying to format it like this
student | English | Software Engeneering |
| int. mark | ext. mark | int. mark | ext. mark |
___________________________________________________________
Josh | 55 | 10 | 45 | 12
Matt | 45 | 12 | 50 | 15
I tried
echo "Student Name\t";
foreach($subject_names as $sub_name)
{
echo "$sub_name\t";
}
echo "<br>";
foreach($table as $sname => $subjects){
echo "$sname\t";
foreach($subjects as $subject_name => $types)
{
foreach($types as $marks)
{
echo "$marks\t";
}
}
echo "<br>";
}
It working fine but if I change the position of array item of table like
$table['Josh'][118]['int'] =55;
$table['Josh'][108]['int'] =45;
$table['Josh'][118]['ext'] = 10;
$table['Josh'][108]['ext'] = 12;
It won't give a correct result. Is there anyway to assure that the result are always correct.
Thank you for your any help and suggestions
Here's a solution I wrote for your request, picking the scores using the $subject_names as control rather than the students' scoresheet (I hope you get what I mean after going through the codes)...
$table=array();
$subject_names=array();
// notice that I switched subject order, just to show that subjects control the marks displayed thereby ensuring consistent score mapping
$subject_names[108]="Software Engeneering";
$subject_names[118]="English";
// and I'm using the rearranged scores (the sample use-case you specified in the question that distorts your output)
$table['Josh'][118]['int'] =55;
$table['Josh'][108]['int'] =45;
$table['Josh'][118]['ext'] = 10;
$table['Josh'][108]['ext'] = 12;
$table['Matt'][118]['int'] =45;
$table['Matt'][118]['ext'] = 12;
$table['Matt'][108]['int'] =50;
$table['Matt'][108]['ext'] = 15;
echo "Student Name\t";
foreach($subject_names as $sub_name)
{
echo "$sub_name\t";
}
echo "\n";
// proposed solution:
foreach($table as $sname => $subjects){
echo "$sname\t";
foreach ($subject_names as $subject_id => $name) {
foreach ($subjects[$subject_id] as $mark) {
echo "$mark\t";
}
}
echo "\n";
}
Here's the output of the script above...
Student Name Software Engeneering English
Josh 45 12 55 10
Matt 50 15 45 12
Running the same data through the script provided in the question, here's the output (distorted)...
Student Name Software Engeneering English
Josh 55 10 45 12
Matt 45 12 50 15
P.S: 'Engeneering' should be 'Engineering'
I hope I've been helpful.
Cheers!
I'm trying to make this works. I want to replace some parts of a sentence between given positions and then show the full sentence with the changes. With the following code, I'm able to make the changes but I don't know how to put together the rest of the sentence.
I have two arrays, one with the positions where a woman name appears and another one with men names. The code replaces the pronoun "his" by "her" when a woman is before a man between the intervals. The last thing I need is to reconstruct the sentence with the changes made but I don't know how to extract the rest of the sentence (the result, in the example, is from positions 0 to 20 (Maria her dress but) and 36 to 51 (Lorena her dog) but I need to extract from 20 to 36 (Peter his jeans) and 51 to the end (Juan his car) to merge them in their positions).
The result should be: "Maria her dress but Peter his jeans Lorena her dog Juan his car". I'll appreciate any help with this, I've been looking for other similar questions but I found nothing.
<?php
$womenpos = array("0","36"); //these arrays are just examples of positions
$menpos = array("20","51"); //they will change depending on the sentence
$sentence = "Maria his dress but Peter his jeans Lorena his dog Juan his car";
echo $sentence."\n";
foreach ($womenpos as $index => $value) {
$value2 = $menpos[$index];
if($value < $value2) {
echo "\nWoman(" . $value . ") is before man(" . $value2 . ")\n";
$end = ($value2 - $value);
$improved = str_replace(' his ', ' her ',
substr($sentence, $value, $end));
echo $improved."\n";
} else {
$improved = "Nothing changed";
echo $improved;
}
}
Ok, how about this:
$womenpos = array("0","36");
$menpos = array("20","51");
$bothpos = array_merge($womenpos,$menpos);
sort ($bothpos);
print_r($bothpos);
$sentence = "Maria his dress but Peter his jeans Lorena his dog Juan his car";
echo $sentence."\n";
for ($i = 0; $i<sizeof($bothpos); $i++) {
$start = $bothpos[$i];
if ($i ==sizeof($bothpos)-1) {
$end = strlen($sentence);
}
else {
$end = $bothpos[$i+1];
}
$length = $end-$start;
$segment = substr($sentence, $start, $length);
if (in_array($start, $womenpos)) {
$new_segment = str_replace (' his ', ' her ', $segment);
}
else { $new_segment = $segment; }
$improved .= $new_segment;
print "<li>$start-$end: $segment : $new_segment </li>\n";
}
print "<p>Improved: $improved</p>";
This combines the men's and women's position arrays to consider each stretch of text as one that might have an error. If that stretch of text starts at one of the womenpos points, then it changes 'his' to 'her'. If not it leaves it alone.
Does this get you in the direction you want to go in? I hope so!
This approaches the problem differently, but I wonder if it would provide the solution you're looking for:
$sentence = "Maria his dress but Peter his jeans Lorena his dog Juan his car";
$women = array ("Maria", "Lorena");
$words = explode (" ", $sentence);
for ($i=0; $i< sizeof($words); $i++) {
if ($words[$i] == "his" && in_array($words[$i-1], $women)) {
$words[$i] = "her";
}
}
print (join(" ", $words));
This goes through the words one at a time; if the preceding word is in the $women array and the current word is "his", it changes the word to "her". Then it spits out all the words in order.
Does this do what you need, or do you really want a complex string positioning answer?
first foreach
foreach (range(1, 70) as $num) {
echo 'Number '.$num.'<br />';
}
second
ksort($numbers);
foreach ($numbers as $key => $value){
echo 'Number '.$key.' = '.$value.' times<br />';
}
First Foreach create numbers list from 1 to 70.
Second Foreach take some info from db ($numbers) like
Number 1 = 1 times
Number 2 = 1 times
Number 6 = 1 times
Number 11 = 1 times
Number 12 = 1 times
Number 13 = 1 times
Number 14 = 1 times
Number 16 = 1 times
Number 17 = 1 times
Number 21 = 2 times
Number 24 = 1 times
Number 25 = 1 times
Number 28 = 1 times
Number 30 = 1 times
Number 31 = 2 times
Number 33 = 1 times
Number 36 = 3 times
Number 38 = 1 times
Number 63 = 1 times
Number 65 = 1 times
Now i need do this work like this:
if($key==$num){
echo 'Number '.$key.' = '.$value.' times<br />';
}else{
echo 'Number '.$key.' = 0 times<br />';
}
All this list from 1 to 70 with show how much times (if exists). Thanks
I would make an associative array for that with the number as key and the value is the number.
$numbers = array();
foreach (range(1, 70) as $num)
{
$numbers[$num] = 0;
}
and with the database loop you combine them
foreach ($dbnumbers as $num => $value)
{
$numbers[$num] += $value;
}
Then you can just iterate over it for displaying ;)
To me, it looks like you're counting occurrences of numbers.
$counter = array();
foreach ($numbers as $num) {
if (!isset($counter[$num]) {
$counter[$num] = 1;
}
else {
$counter[$num]++;
}
}
print_r($counter); # You have all of your occurrences loaded into this tidy array.
OK here is what i want to do
I have an array that contains keywords
$keywords = array('sport','messi','ronaldo','Barcelona','madrid','club','final','cup','player');
and i have another array that contains my whole titles
let's say
$titles = array('Real Madrid is the only club to have kept a European cup by winning it five times in a row.','Cristiano Ronaldo is World Soccer's Player of the Year 2013.','Lionel Messi Reaches $50 Million-A-Year Deal With Barcelona','','');
so now what i want to do
is to loop my keywords array in each of the titles array element
and if there is 3 keywords in one element then do something
for example
$titiles[0] // this one has these words => Madrid , cup club
so this one is have at least 3 words of my keywords
so if each element has 3 keywords or more , then echo that array element.
any idea on how to get this working?
foreach ($titles as $t){
$te=explode(' ',$t);
$c=count(array_intersect($te,$keywords));
if($c >=3){
echo $t.' has 3 or more matches';
}
}
live demo: http://codepad.viper-7.com/7kUUEK
2 matches is your current max
if you want Madrid to match madrid
$keywords=array_map('strtolower', $keywords);
foreach ($titles as $t){
$te=explode(' ',$t);
$comp=array_map('strtolower', $te);
$c=count(array_intersect($comp,$keywords));
if($c >=3){
echo $t.' has 3 or more matches';
}
}
http://codepad.viper-7.com/itdegA
Alternatively, you could also use substr_count() to get the number of occurances. Consider this example:
$keywords = array('sport','messi','ronaldo','Barcelona','madrid','club','final','cup','player');
$titles = array('Real Madrid is the only club to have kept a European cup by winning it five times in a row.',"Cristiano Ronaldo is World Soccer's Player of the Year 2013.","Lionel Messi Reaches $50 Million-A-Year Deal With Barcelona",'','');
$count = 0;
$data = array();
foreach($titles as $key => $value) {
$value = strtolower($value);
$keys = array_map('strtolower', $keywords);
foreach($keys as $needle) {
$count+= substr_count($value, $needle);
}
echo "In title[$key], the number of occurences using keywords = " .$count . '<br/>';
$count = 0;
}
Sample Output:
In title[0], the number of occurences using keywords = 3
In title[1], the number of occurences using keywords = 2
In title[2], the number of occurences using keywords = 2
In title[3], the number of occurences using keywords = 0
In title[4], the number of occurences using keywords = 0
Fiddle
Simpler with array_intersect:
$keywords = array('sport','messi','ronaldo','Barcelona','madrid','club','final','cup','player');
$titles = array('Real Madrid is the only club to have kept a European cup by winning it five times in a row.','Cristiano Ronaldo is World Soccer\'s Player of the Year 2013.','Lionel Messi Reaches $50 Million-A-Year Deal With Barcelona');
foreach($titles as $title) {
if (count(array_intersect(explode(' ',strtolower($title)), $keywords)) >= 3) {
//stuff
}
}
Bear with me here--this may be a bit confusing.
I am retrieving two sets of data with SQL. Here's the code, with the query. I'm using Zend Framework.
$assignments = $db->fetchAll("SELECT id,name,class FROM assignments");
foreach($assignments as $a) {
$assignmentID = $a['id'];
$studentData = $db->fetchAll(
"SELECT student,assignment,status,assignmentID FROM student_assignments WHERE assignmentID='$assignmentID'"
);
echo "<th>".$a['name']."</th>";
foreach($studentData as $s) {
$bottom .= "<tr><td>" . $s['student'] . " " . $s['assignmentID']
. " ".$s['status'] . "</td></tr>";
$i++;
}
}
echo "</tr>$bottom;";
Here's what the output looks like in the HTML:
|Assignment on 07/07/2012| |Assignment on 07/12/2012| |Assignment on 07/15/2012|
117 1 Y
332 1 N
36 1 N
420 1 N
332 1 Y
326 2 N
212 2 N
461 2 N
117 2 N
212 2 N
212 3 N
326 3 N
117 3 Y
420 3 Y
Now the top part is working great -- it's dynamically showing each assignment in the database. But I've been trying to figure out a way to get the appropriate data to show under those columns, to no effect. This is the closest I've gotten to making it look somewhat correct.
Essentially, the data that has "2" and "3" in the middle should go into the 2nd and 3rd columns, respectively. But this isn't happening because all the data is stored into the $bottom variable, rather than the data for each assignment.
Does anyone have any suggestions? This is driving me crazy, and I feel like the solution is staring me in the face.
Thanks!
First you want to iterate through every of your student assignments, and left join the assignments table to it so you can know the name of the assignment that it is related to.
$students = $db->fetchAll('SELECT sa.student,sa.assignment,sa.status,sa.assignmentID,a.name
FROM student_assignments AS sa
LEFT JOIN assignments AS a ON sa.assignmentID=a.id');
Then with the results, you can build an array to regroup everyone with the same assignment:
$columns = Array();
foreach($students as $s) {
$row = '<tr><td>'.$s['student'].' '.$s['assignmentID'].' '.$s['status'].'</td></tr>';
array_push($columns[$s['name']], $row);
}
Then with this array, you can finally print your content:
foreach ($columns as $key=>$value) {
echo '<th>'.$key.'</th>';
foreach ($value as $v) {
echo $v;
}
}
Of course this can be more compact (reduced into nested loops), and I have no way to fully test it, but it should help you in your process ;)