I'm using below code to display Image & Name of webisites form database.
<fieldset>
<h1>A</h1>
<ul>
<?php foreach ($records as $key) { ?>
<li class="siteli"> <a href="#" class="add">
<div id="site-icon"><img src="<?php echo $key->site_img; ?>" width="16" height=""></div>
<p id="text-site"> <?php echo $key->site_name; ?></p>
</li>
<?php } ?>
</ul>
</fieldset>
Now I'm trying to group this results alphabetically by adding A, B, C etc as title.
Example,
A
Amazon
Aol
Aol Mail
B
Bing
Bogger
You can use array sorting to sort the array. In your case I would choose sort()
Now to show the links with a preceding Letter I would use:
<?php
$records = ['Aaaaa', 'Aaaa2', 'bbb', 'bbb2', 'Dddd'];
$lastChar = '';
sort($records, SORT_STRING | SORT_FLAG_CASE); //the flags are needed. Without the `Ddd` will come before `bbb`.
//Available from version 5.4. If you have an earlier version (4+) you can try natcasesort()
foreach($records as $val) {
$char = $val[0]; //first char
if ($char !== $lastChar) {
if ($lastChar !== '')
echo '<br>';
echo strtoupper($char).'<br>'; //print A / B / C etc
$lastChar = $char;
}
echo $val.'<br>';
}
?>
This will output something like
A
Aaaa2
Aaaaa
B
bbb
bbb2
D
Dddd
Notice that the C is missing, because there are no words starting with C.
This is a modification of #Hugo Delsing's answer.
I needed to be able to group my brands together like this, but one bug in the code was the fact that if I had say iForce Nutrition and Inner Armour it would group these into two separate groups because of the letter case.
Changes I Made
Because it was fully alphabetical, it was only going by first letter I changes SORT_STRING to SORT_NATURAL
Changed: if ($char !== $lastChar) to if (strtolower($char) !== strtolower($lastChar))
<?php
$records = ['FinaFlex', 'iForce Nutrition', 'Inner Armour', 'Dymatize', 'Ultimate Nutrition'];
$lastChar = '';
sort($records, SORT_NATURAL | SORT_FLAG_CASE); //Allows for a full comparison and will alphabetize correctly.
foreach($records as $val) {
$char = $val[0]; //first char
if (strtolower($char) !== strtolower($lastChar)) {
if ($lastChar !== '')
echo '<br>';
echo strtoupper($char).'<br>'; //print A / B / C etc
$lastChar = $char;
}
echo $val.'<br>';
}
?>
The final output will be like this
D
Dymatize
F
FinaFlex
I
iForce Nutrition
Inner Armour
U
Ultimate Nutrition
I hope this helps everyone, and a big thank you to Hugo for providing the code that got me exactly where I needed to be.
You can see my example here https://hyperionsupps.com/brand-index
$records = ['FinaFlex', 'iForce Nutrition', 'Inner Armour', 'Dymatize', 'Ultimate Nutrition'];
$temp=array();
$first_char="";
for($i=0;$i<count($records);$i++)
{
$first_char= strtoupper ($records[$i][0]);
if(!in_array($first_char, $temp))
{
echo strtoupper($first_char).'<br>'; //print A / B / C etc
}
$temp[]= $first_char;
echo $records[$i]."<br>";
}
Related
This is the code i have by now:
<?php
$sql = DB::query("SELECT name FROM stores ORDER BY name");
foreach ($sql as $row){ $name = $row["name"]; }
// don't know how to get the current letter
$current_letter = '?';
// Set the start at 1
$i = 1;
foreach ($sql as $row){
// If the loop hits 1, add <div>
if($i == 1)
echo '<div class="store-wrapper">'.PHP_EOL;
echo '<div class="store-letter">Store Letter - '. $current_letter .'</div>'.PHP_EOL;
echo '<ul>'.PHP_EOL;
echo $id = "\t<li>".$name.'</li>'.PHP_EOL;
// If the loop hits 3, add </div>
if($i == 3) {
echo '</ul>'.PHP_EOL;
echo '</div>'.PHP_EOL; // end .store-wrapper
// Reset the counter
$i = 0;
}
// Increment up
$i++;
}
?>
Is there something wrong with my code? This is the code output that i am trying to achieve:
<div class="store-wrapper">
<div class="store-letter">Store Letter - A</div>
<ul>
<li>ajhgjgj</li>
<li>abgjkhjh</li>
<li>avbnvnmnm</li>
</ul>
</div>
<div class="store-wrapper">
<div class="store-letter">Store Letter - B</div>
<ul>
<li>bgfghfj</li>
<li>bhgjhgj</li>
<li>bvkjhgkj</li>
</ul>
</div>
<div class="store-wrapper">
<div class="store-letter">Store Letter - C</div>
<ul>
<li>cgfghfj</li>
<li>chgjhgj</li>
<li>cvkjhgkj</li>
</ul>
</div>
Another thing is that i don't really know how to get the first letter of each group.
The problem with the code is that the output does not display as the upper example and the groups don't jumb to the next available letter when maximum 3 <li> are reached.
What i am doing wrong?
You don't need the first foreach loop. It just repeatedly assigns the same variable $name. You can do this in the loop that echoes the DIVs.
You can get the first letter of a string with $name[0].
Rather than testing for $i == 3 to know when to close the UL and DIV, test for $i > 3 to skip printing the names. Otherwise, if a letter has only 1 or 2 names in its group, you'll never close the group.
$current_letter = null;
foreach ($sql as $row) {
$name = $row['name'];
$first_letter = $name[0];
if ($first_letter != $current_letter) {
$i = 1;
if ($current_letter) { // close the previous DIV before starting new one
echo '</ul>'.PHP_EOL;
echo '</div>'.PHP_EOL;
}
$current_letter = $first_letter;
echo '<div class="store-wrapper">'.PHP_EOL;
echo '<div class="store-letter">Store Letter - '. $current_letter .'</div>'.PHP_EOL;
echo '<ul>'.PHP_EOL;
}
if ($i > 3) {
continue;
}
echo "\t<li>".$name.'</li>'.PHP_EOL;
$i++;
}
if ($current_letter) { // close the last DIV
echo '</ul>'.PHP_EOL;
echo '</div>'.PHP_EOL;
}
DEMO
output
1.Without using for loop, you can also use array_column() php function in order to get only 'name' from $sql. For example, $test = array_column($sql,'name');.
2.After that $test[0] will give you first name in the array.
3.To get first character, use substr($test[0], 0, 1)
I'm trying to achieve a loop over all possible 2 letter combinations.
Something like
foreach(range(aa,zz) as $i) {...}
My current solution is:
foreach (range(a, z) as $first) {
foreach (range(a, z) as $second) {
//all 2 letter combinations
echo $first.$second;
}
}
This makes me worry that if I needed all possible 10 letter combinations, there would be 10 loops involved.
Is there a better way to achieve this?
You could loop over letters using a simple for loop :
for ($letter = 'aa'; $letter != 'aaa'; ++$letter) {
echo $letter . '<br>';
}
Output :
aa
ab
...
zy
zz
$a = array(1,2,3,4,5,6,7,8,9,0);
$b = array('q','r','s','t','u','v','w','x','y','z');
for($i = 26;$i <= 1000;$i++)
echo str_replace($a,$b,base_convert ( $i, 10 , 26))."<br />";
just put in the right starting and end positions.
I'm trying to imitate how the Windows "Map Network Drive" dropdown works. My dropdown options are the letters A-Z. Based on the results from my SQL SELECT statement, I need to show but disable those letters that are already in use. I'm able to get the letters in the dropdown, or get my SQL results in the dropdown but not the correct combination of both.
How do I display all letters of the alphabet in a dropdown and disable those that come back in my SQSL SELECT statement?
Example DB
ID | Desc
-----------
A | Desc A
D | Desc D
F | Desc F
J | Desc J
Z | Desc Z
So for example, using the example DB above, the letters 'A, D, F, J, Z' would be displayed but disabled whereas all other letters in the alphabet would be selectable.
This is the code I currently have. It's very close to being correct but somehow out of order. It does display every letter of the alphabet and my database results (with those results disabled) BUT every letter of the alphabet is displayed for every database result. Again using the Example DB above, the code below would display the letters 'A' through 'Z' for each result (5 times) and each time disable that result only.
<select>
<?php
// SQL select from Example DB table and connection
while ($row = odbc_fetch_array($db)) {
foreach (range('A', 'Z') as $value) {
if ($row['id'] == $value) {
$result = $value.' -- '.$row['desc'];
$dis = "disabled";
} else {
$result = $value;
$dis = "";
}
?>
<option <?php echo $dis; ?>><?php echo $result; ?></option>
<?php
}
}
?>
</select>
I've tried moving the 'while' and 'foreach' around but haven't seemed to get them in the correct order.
You need to first query your database for letters in use, and then create a looping statement that goes from A to Z, and either marks the <option> as disabled or not.
<?php
$inUse = array();
$sql = "SELECT UNIQUE(`ID`) FROM `table` ORDER BY `ID` ASC";
$res = $db->query($sql);
foreach ($drive as $res->fetchObject()) {
$inUse[] = $drive['ID'];
}
// create select list
echo '<select name="drive">';
foreach (range('A', 'Z') as $letter) {
$disabled = (in_array($letter, $inUse)) ? ' disabled="disabled"' : '';
echo '<option value="' . $letter . '"' . $disabled . '>' . $letter . '</option>';
}
echo '</select>';
Untested, but you could try this:
<select>
<?php
$range = range('A', 'Z');
$used = array();
// Fill in used drives along with their descriptions
while ($row = odbc_fetch_array($db)) {
$used[$row['ID']] = $row['desc']);
}
foreach ($range as $value) {
$result = $value;
$dis = "";
if (in_array($value, $used) {
$result .= ' -- '.$used[$value];
$dis = 'disabled="disabled"';
}
?>
<option <?php echo $dis; ?>><?php echo $result; ?></option>
<?php
}
?>
</select>
I want to make something like this:
A1
B1
C1
D1
D2
D3
C2
C3
B2
C4
D10
D11
D12
C5
C6
B3
C7
C8
C9
D25
D26
D27
So it's always groups of three, with every level ascending by a letter. First level is A, second B, C, D, E and so forth. The numbers are also listed in ascending order. Level A can only reach 1, B has 3, C has 9, D has 27, and so forth.
This is really easy to generate manually, converting the letters to their ASCII equivalent, adding one and converting them to character equivalent again. Problem is, I have to loop it till S, for instance, and my mind is getting messier and messier trying to put loops within loops.
What I got (toLetter and toNumber literally does what they do):
echo "<ul><li>";
echo "A1";
echo "<ul><li>";
$b = toNumber(A);
$b++;
$b = toLetter($b);
$bnum = 1 - 1;
$bnum = $bnum * 3;
$bnum++;
echo $b;
echo $bnum."</li>";
$bnum++;
echo "<li>".$b;
echo $bnum."</li>";
$bnum++;
echo "<li>".$b;
echo $bnum."</li>";
Making this:
A1
B1
B2
B3
I really can't figure out how to just loop everything so it can reach till Z.
A pretty simple version which only goes up to the 'C' level; increase as necessary.
<?php
function outputListItems($char) {
static $index = array('A' => 1);
if (!isset($index[$char])) {
$index[$char] = 1;
}
for ($i = 0; $i < 3; $i++) {
echo '<li>';
echo $char;
echo $index[$char]++;
if ($char < 'C') {
echo '<ul>';
$nextChar = $char;
outputListItems(++$nextChar);
echo '</ul>';
}
echo '</li>';
}
}
?>
<ul>
<li>
A1
<ul><?php outputListItems('B'); ?></ul>
</li>
</ul>
A is treated as special chase, since it only has one entry.
in PHP, you can use ++ on a string, so you don't need to Letter/toNumber
And to support unlimited nesting, you need a recursion (or at least it will be easier for you)
I have the following test code:
<?php
$letter = 'A';
$letter++;
$letter++;
echo $letter.'<br>'; // C
$letter++;
$letter++;
$letter++;
echo $letter.'<br>'; // F
// how to add plus 3 letters
// so that
// $letter + 3 => I
As shown here by using $letter++ or $letter-- I can go up or down a character. Is there a way I can do something like $letter + 3 so it adds up 3 letters.
I know I can make a function with a loop which will add a char by char and at the end I will get the result. But is there a better way?
There might be better solutions but the fastest way I can think of is:
// get ASCII code of first letter
$ascii = ord('A');
// echo letter for +3
echo chr($ascii + 3);
keep in mind that you will get other symbols after Z
Try this...
$letter = ord('A')+3;
echo chr($letter);
Maybe this'll work:
$x = 'G';
$y = range('A','Z');
echo $y[array_search($x,$y)+3];
Old thread but in case someone searches. Create array of letters, needed letter as in spreadsheet.
$alphabet = array('A','B','C','D','E','F','G','H','I','J','K','L','M',..........'AY','AZ');
//add 36 to the letter A
$val = (array_search('A',$alphabet)) + 36;
echo $alphabet[$val]."<BR>";
I don't really like any of these answers as they don't replicate the function of PHP. Below is probably the easiest way to replicate it.
function addLetters($letter,$lettersToAdd){
for ($i=0;$i<$lettersToAdd;$i++){
$letter++;
}
return $letter;
}
echo addLetters('G',4);
echo "\n";
echo addLetters('Z',4);
Gives
K
AD