Ascending Numbers from array for each individual element - php

I didnĀ“t get an answer yesterday on this question. https://stackoverflow.com/questions/15206351/jquery-slider-with-newest-content-first-gets-reversed-thumbnails-clicking-on-fi
So I tried for a simpler solution. I want to change this code:
$news_countpp = 6;
$result = mysqli_query($con,"SELECT * FROM tbl_news ORDER BY id DESC LIMIT ".($news_page * $news_countpp).", $news_countpp");
while($row = mysqli_fetch_array($result))
{
echo "<div><a href='#".$row['id']."' class='cross-link'><img src='/assets/images/news/news_".$row['id']."_slider_thumb.jpg' alt='".$row['news_img_alt']."' class='nav-thumb' alt='temp-thumb' style='width:60px; height:40px;'></a></div>";
}
The Part <a href='#".$row['id']." would echo descending numbers from #6 - #1. (newest news hast highest ID)
I want the numbers to be ascending instead (not according to the id) than it works.
I tried the following array instead of ".row['id'].":
$thumblink = array ('1', '2', '3', '4', '5', '6');
for ($i = 0; $i < 6; $i++) {
echo $thumblink[$i];
}
But this gives each of my 6 thumbnails the href "123456" instead of ascending numbers from 1 - 6 for the individual thumbnails. Do you know what I do wrong?

$news_countpp = 6;
$result = mysqli_query($con,"SELECT * FROM tbl_news ORDER BY id DESC LIMIT ".($news_page * $news_countpp).", $news_countpp");
$i = 1
while($row = mysqli_fetch_array($result))
{
echo "<div><a href='#".$i."' class='cross-link'><img src='/assets/images/news/news_".$row['id']."_slider_thumb.jpg' alt='".$row['news_img_alt']."' class='nav-thumb' alt='temp-thumb' style='width:60px; height:40px;'></a></div>";
$i++;
}

I would guess you're iterating over the entire array for every iteration of the while loop. Instead, initialise the array and a counter variable to 0 prior to the while loop, and only access one element per iteration (incrementing the counter by one as you do so).

How about something like this?
$i = 0;
while($row = mysqli_fetch_array($result)) {
$i++;
echo
"<div>",
"<a href='#".$row['id']."' class='cross-link'>",
"<img src='/assets/images/news/news_", $row[$i], "_slider_thumb.jpg'
alt='".$row['news_img_alt']."'
class='nav-thumb' alt='temp-thumb'
style='width:60px; height:40px;'>",
"</a>",
"</div>";
}

Related

Php foreach split list into columns (preferably equally)

I have an ordered list which is 19 entries long (but could change and be more or less). I'm listing it on a drop down menu but because of its length the column is dropping below the fold of the page.
I'd like to create a separate column (ul or div) to either divide the list into 2 or 3 equally, or have set list sizes e.g. max 7 per list.
Any ideas? Current code:
<div id="colour" class="dropmenudiv">
<?php
$sql = "select * from rug_colours where id <> 0 and active = 1 order by name";
$rs = $database->query($sql);
$index = 0;
foreach($rs as $v) {
echo "<a href=\"//$base_url/?action=search&colour=".$v['id']."\" >".$v['name']."</a>";
}
?>
Try something along the lines of:
<div id="colour" class="dropmenudiv">
<?php
$sql = "select * from rug_colours where id <> 0 and active = 1 order by name";
$rs = $database->query($sql);
$column_height = 7;
echo "<div class='column'>";
foreach($rs as $idx => $v) {
echo "<a href=\"//$base_url/?action=search&colour=".$v['id']."\" >".$v['name']."</a>";
if($idx % $column_height) echo "</div><div class='column'>";
}
echo "</div>";
?>
and for equal split you might try this:
$max_column_height = 7;
$no_of_cols = ceil(count($rs) / $max_column_height);
$column_height = floor($count($rs) / $no_of_cols);
You should use index variable to divide it into 2 or 3 div.
Following is example to make it in three parts:
$index = 0;
foreach($rs as $v) {
if($index > 7){
$index = 0; // reset to zero. You can also seperate it by any tag div or ul if you want
}
echo "<a href=\"//$base_url/?action=search&colour=".$v['id']."\" >".$v['name']."</a>";
$index++;
}
For an evenly spread distribution, first divide the number of elements by 7 (or whichever maximum rows you want to allow), rounding upwards. This gives the number of columns. Then divide the number of elements by the number of columns, rounding upwards: this gives you the actual number of rows you need.
I like array_chunk for this purpose:
$maxRowCount = 7;
$colCount = ceil(count($rs) / $maxRowCount);
$chunkSize = ceil(count($rs) / $colCount);
foreach(array_chunk($rs, $chunkSize) as $column) {
echo "<div class='column'>\n";
foreach($column as $v) {
echo "<a href=\"//$base_url/?action=search&colour={$v['id']}\" >{$v['name']}</a>";
}
echo "</div>\n";
}
You can create array of columns based on current index in foreach() loop like
$abc = [1,2,3,4,5,6,7,8,9,10,11,12,13,14,15];
$cols = [];
$perCol = 7;
foreach($abc as $index => $val) {
$colInd = $index / $perCol;
$cols[$colInd][] = $val;
}
print_r($cols);
This will split data in $abc into 3 coluns by 7 items per column.

PHP Count Generated Results From Loop

I have this for loop that generates 10 results:
<?php
include "dbconnect.php";
$table = "SELECT id FROM players ORDER BY RAND()* ( 1 / percentage)";
for ($i = 0; $i < 10; $i++){
$result[0] = mysql_fetch_array(mysql_query($table));
foreach ($result as $winner){
echo $winner[0] . " ";
}
}
?>
It generates a result like:
10 10 11 9 13 11 10 12 8 12
My question is how do I count the generation? For the above example it would be:
8's = 1, 9's = 1, 10's = 3, 11's = 2, 12's = 2, 13's = 1.
I basically want to count the amount of specific results generated. Sorry if i'm not making much sense.
You need to get off of MySQL functions and check out PDO or MySQLI at a minimum. But for the meat of the question:
Don't run a query, full or limited in the loop
Look at the LIMIT clause in the query
array_count_values will count the values. You can loop it and echo or whatever
Example:
$table = "SELECT id FROM players ORDER BY RAND()*(1/percentage) LIMIT 10";
$result = mysql_query($table);
while($row = mysql_fetch_array($result)) {
$winner[] = $row[0];
}
echo implode(' ', $winner);
foreach(array_count_values($winner) as $number => $count) {
$output = "$number's = $count";
}
echo implode(', ', $output);
You're existing code to make the random choice work would look like (LIMIT 1):
$table = "SELECT id FROM players ORDER BY RAND()*(1/percentage) LIMIT 1";
for($i = 0; $i < 10; $i++){
$result = mysql_fetch_array(mysql_query($table));
$winner[] = $row[0];
}
echo implode(' ', $winner);
if you check the php manual:
http://php.net/manual/en/function.mysql-query.php
then try something like this:
while ($row = mysql_fetch_assoc($table)) {
echo $row['column_name'];
echo $row['column_name'];
//.. you get the idea
}
The id is usually the first column in a database table. This is why you are just getting the id. You need to access each row in the same way you access arrays.
I should point out that the mysql library is deprecated. So you should consider using something like PDO instead.

PHP Loop Detect First Instance of each Letter of MySQL results

If I query a database with PHP using MySQLi, how can I detect the first instance of each letter of the alphabet?
If I have a table like -
ID | name
1 Allen
2 John
3 Sally
4 William
and I query
SELECT * FROM table ORDER BY name ASC
Can I have something in my loop that says "if this is the first time you've seen the string in name start with the letter A", echo <a id="a"></a> to create an anchor tag? Then it will proceed to do the same for B,C,D,E,F,G, etc.. Then I can create an alphabetical legend.
Here is my query and loop:
$query = "SELECT * FROM table ORDER BY name ASC";
$result = $db->query($query);
$num = $result->num_rows;
for($i=0; $i < $num; $i++){
$row = $result->fetch_object();
//IF THIS IS THE FIRST TIME SEEING $row->name START
//WITH A DIFFERENT LETTER OF THE ALPHABET ECHO SOMETHING...
echo $row->name;
}
Create an associative array that records which letters you've seen.
$letters_seen = array();
while ($row = $result->fetch_object()) {
$letter = substr($row->name, 0, 1);
if (!isset($letters_seen[$letter])) {
// This is the first time seeing this initial letter
$letters_seen[$letter] = true;
echo "<a id='$letter'>$letter</a>";
}
echo $row->name;
}
Since your results are ordered by name, if the first letter of the current row doesn't match the first letter of the previous row, then you know it's the first time you've seen it.
$previousLetter = '';
for($i=0; $i < $num; $i++){
$row = $result->fetch_object();
if($row->name[0] != $previousLetter) {
echo "<a id='" . $row->name[0] . "'></a>";
$previousLetter = $row->name[0];
}
echo $row->name;
}

Complicated Star Pattern?

Okay, so I have a unique problem that I ran into when trying to code a 5x3 star pattern. I can do the for loops to get the 5x3, that's easy. However I need something different than a square.
We can have a maximum of 15 stars. So printing out a full block would look like this:
* * *
* * *
* * *
* * *
* * *
But we can pass in a parameter for the number of stars that we want. So let's pass in 11 instead of 15. We should get:
* * *
* * *
* * *
* *
However, with 11 as my parameter the output is like this:
*
* *
* *
*
It prints out the correct number of rows with the incorrect number of stars. I know why this is, and it's because of the modulus in my code. I also tried a different approach, which printed out one less row than needed. I am stuck and not sure where to go from here.
Here is my code:
<?php
$num = 11;
$rows = ceil($num/3);
$count - 0;
for($j = 0; $j < $rows; $j++){
echo '<div class="row-fluid"><ul class="thumbnails">';
for($i = $num%3; $i < 3; $i++){
echo '*';
$count++;
}
$num-=$count;
echo '</ul></div>';
}
?>
With some simple PHP-Fu:
$stars = 11;
$row_length = 3;
$array = array_fill(0, $stars, '*');
$array = array_chunk($array, $row_length);
$table = '<table border="0">';
foreach($array as $row){
$table .= '<tr><td>'. implode('</td><td>', $row) .'</td></tr>';
}
$table .= '</table>';
echo $table;
Online demo.
The idea should be as simple as: keep drawing until you reach the target number.
So you could do this:
$num = 11;
for( $i=0; $i<$num; $i+=3) {
echo "<div class=\"row-fluid\"><ul class=\"thumbnails\">";
for( $j=0; $j<3 && $i+$j<$num; $j++) {
echo "*";
}
for( ; $j<3; $j++) { // finish the current row (optional, remove if not needed)
echo " ";
}
echo "</ul></div>";
}
Ooh a puzzle!
I don't know if using for was a requirement for your assignment, I prefer while.
$num_of_stars = 15;
$stars_per_row = 3;
while($num_of_stars > 0){
echo "*";
if($stars_per_row == 1){
$stars_per_row = 3;
echo "<br />";
}else{
$stars_per_row --;
}
$num_of_stars --;
}
I don't see why you would have to use two for-loops.
I would do something like this: (I noticed you don't have any <li>'s in your code) Of course you would have to set the class="thumbnails" to include list-style-type:none;
<?php
$num = 11;
$cols = 3;
echo '<div class="row-fluid"><ul class="thumbnails">';
$count = 0;
for($j = 0; $j < $num; $j++){
$count++;
echo '<li style="float:left;">*</li>';
if ($count>=$cols) {
$count = 0;
echo '<li style="clear:both;"></li>';
}
}
echo '</ul></div>';
?>
For this to work, this is what you need.
$num = 11;
$cols = 3;
$rows = ceil($num/$cols);
for($j=0;$j<$rows;$j++)
echo "<div class='row'>";
for($i=0;$i<$cols;$i++){
echo "*";
}
echo "</div>";
}
To show where you went wrong in your code. First, your definition of $count should be = not -. Next, your inner for loop is odd.
First loop through, $num is equal to 11. In your inner loop you set $i = $num%3 which is $i = 2. So the inner loop runs through once while $i++ < 3, echo's one star and increments count once. inner loop exits, you subtract $count from $num making $num=10 and row is completed, next outer loop iteration.
Next time the inner loop runs, $num is 10 so $i = $num%3 becomes $i=1. Inner loop runs 2 times while $i++ < 3, echo'ing 2 more stars and incrementing $count both times making it now 3. after the inner loop you subtract 3 more from $num making it 7 and row ends, outer loop continues.
Next inner loop, $num is 7 so $i = $num%3 becomes $i=1. Inner loop runs 2 times while $i++ < 3, echo'ing 2 more stars and incrementing $count both times making it now 5. after the inner loop you subtract 5 from $num making it now 2, row ends, outer loop continues.
Last iteration of the outer loop (row limit hit), $num is 2 so $i = $num%3 becomes $i=1. Inner loop runs once, echo's one star and inrement count once making it now 8. Inner loop finishes, you subtract 8 from $num making it now -6, row ends, outer loop ends.

PHP loop to sort table

I'm querying a database for names that are numbered 1-26 alphabetically. I have the following code, but since HTML is structured tr then td, the table appears alphabetically by row as opposed to by column. How can I make it appear in order by column?
$query = mysql_query("SELECT name FROM people WHERE main=1 ORDER BY id");
$i = 0;
while($result = mysql_fetch_array($query)) {
$name = $result['name'];
if ($i % 5 == 0) echo "<tr>\n";
echo "<td width=\"150\">";
echo "".$name."<br />";
echo "</td>\n";
$i++;
if ($i % 5 == 0) echo "</tr>\n";
};
alpha beta charlie
delta echo foxtrot
vs.
alpha charlie echo
beta delta foxtrot
Also, I'm open to reworking the code if there's a more efficient way.
You could just access the output array in strides. Compute how many rows you need as the number of results divided by 5, and use the row count as the stride.
$ncols = 5;
$nrows = $nresults / $ncols + ($nresults % $ncols == 0 ? 0 : 1);
for ($i = 0; $i < $nrows; $i++)
{
// start row
for ($j = 0; $k < $ncols; $j++)
{
// print $results[$nrows * $j + $i]
}
// end row
}
You'll have to transfer your query results into an array $results first. Since you'll have to know the total number of results, this is sort of mandatory, though I'd be curious if anyone has a solution that can work while fetching the results.
Update: See Justin's answer for a cool solution that grows the output while fetching the query results line by line. Since it's currently being worked on, here's a summary (credits to Justin):
$nresults = mysql_num_rows($query);
$ncols = 5;
$nrows = (int) ceil($nresults / $ncols);
$i = 0; $cols = array_fill(0, $nrows, "");
while ($result = mysql_fetch_array($query))
$cols[$i++ % $nrows] .= "<td>$result['name']</td>";
echo "<tr>" . implode("</tr><tr>", $cols) . "</tr>";
Edit:
After the discussion in the comments between myself, Kerrek SB and the OP bswinnerton, the following code seems to be the most effective:
$columns = 3;
$rowcount = mysql_num_rows($query);
$rows = ceil($rowcount / $columns);
$rowdata = array_fill(0, $rows, "");
$ctr = 0;
while ($result = mysql_fetch_array($query))
$rowdata[$ctr++ % $rows] .= '<td>'.$result['name'].'</td>';
echo '<tr>'.implode('</tr><tr>',$rowdata).'</tr>';
This will create three columns, filled vertically (my original answer would create three rows). It also properly initializes the array (preventing PHP warnings), yields a correct row count for result counts that aren't divisible by the column count, and incorporates Kerrek's clever "calc-row-in-the-subscript" trick.
Original Post:
You could use arrays and implode() This way, you only have to make one pass through your results:
$row = 0;
$rows = 3;
$rowdata = array();
while($result = mysql_fetch_array($query))
{
if ($row >= $rows) $row = 0;
$rowdata[$row++] .= '<td>'.$result['name'].'</td>';
}
echo '<tr>'.implode('</tr><tr>',$rowdata).'</tr>';

Categories