Jump to content

Recommended Posts

I've created an alphabetical listing code which more or less works, but I would like to expand on the information it outputs to the viewer.  Currently it only outputs two fields, the $title and $author.  I would also like to add the $url field to the output, but simply adding this:

 

$url= $records['url'];

 

doesn't created a relationship to the outputted information.  What that means if I do insert the $url into the echo, it will simply retrieve the $url for the final outputted row and assign that to all of the outputted lists, like so:

 

table

title1, author1, url1

title2, author2, url2

title3, author3, url3

 

Right now it outputs this:

 

title1 by author1 at url3

title2 by author2 at url3

title3 by author3 at url3

 

How would I create a relationship between the outputted rows and their respective $url using the code below?

 

<?php

$sql = "SELECT *, UPPER(SUBSTRING(title,1,1)) AS letter FROM feudal WHERE `type` = 'Fanart' GROUP BY title, author ORDER BY title";
$query = mysql_query( $sql ) or die(mysql_error());

while ($records = @mysql_fetch_array ($query)) {
$alpha[$records['letter']] += 1;
${$records['letter']}[$records['author']] = $records['title'];

$url= $records['url'];
}

echo '<ul class="alphabet">
<li><a href="#other">#</a></li>';

// Create Alpha link Listing
foreach(range('A','Z') as $i) {
echo (array_key_exists ("$i", $alpha)) ? '<li><a href="#'.$i.'">'.$i.'</a></li>' : '<li>'.$i.'</li>';
}

echo '</ul><ol class="listfanart">';

// Create Data Listing
foreach(range('A','Z') as $i) {
if (array_key_exists ("$i", $alpha)) {
echo '<a name="'.$i.'"></a><h3>'.$i.'<div style="font-size: 10px; float: right;"><a href="#">top</a></h3>';
foreach ($$i as $key=>$value) {
echo '<li><a href="'.$url.'" target="_blank">'.$value.'</a> by '.$key.'</li>
';

}
}
}

?>

 

in the second chunk

 

// Create Data Listing

foreach(range('A','Z') as $i) {

if (array_key_exists ("$i", $alpha)) {

echo '<a name="'.$i.'"></a><h3>'.$i.'<div style="font-size: 10px; float: right;"><a href="#">top</a></h3>';

foreach ($$i as $key=>$value) {

echo '<li><a href="'.$url.'" target="_blank">'.$value.'</a> by '.$key.'</li>

';

 

 

change $i to $j

 

like this (untested)

 

// Create Data Listing

foreach(range('A','Z') as $j) {

if (array_key_exists ("$j", $alpha)) {

echo '<a name="'.$j.'"></a><h3>'.$j.'<div style="font-size: 10px; float: right;"><a href="#">top</a></h3>';

foreach ($$j as $key=>$value) {

echo '<li><a href="'.$url.'" target="_blank">'.$value.'</a> by '.$key.'</li>

';

 

change $i to $j

 

Isn't that a little like rearranging the deck chairs on the Titanic?  The problem isn't with the existing variables, but the fact that the $url field has no correlation to either $value or $key ($title and $author, respectively).  What I need is to find is some way to relate the $url field to the $record which is outputted in the final echo of the code.

lol great analogy.  I only said that because by your sample output it looked like your loop wasn't resetting.  I think you answer needs to be an array of 2d arrays.

 

array[0]['title'] = x;

array[0]['author'] = y;

array[0]['url'] = z;

 

or you can make an object

then access it by object.title

object.author and object.url

 

you can use a foreach loop for both the 1x2d array and the object to loop through. Do whichever is most comfortable.

I am remotely familiar with arrays (translation: barely grasping the concept), but to be honest I've never heard of using a '2d array' nor making an 'object.'  How does one do these things (especially with the current mess I've given as code)?

try

<?php

$sql = "SELECT *, UPPER(SUBSTRING(title,1,1)) AS letter FROM feudal WHERE `type` = 'Fanart' GROUP BY title, author ORDER BY title";
$query = mysql_query( $sql ) or die(mysql_error());

while ($records = @mysql_fetch_array ($query)) {
$alpha[$records['letter']][] = $records;
//	${$records['letter']}[$records['author']] = $records['title'];

//	$url= $records['url'];
}

echo '<ul class="alphabet">
<li><a href="#other">#</a></li>';

// Create Alpha link Listing
foreach(range('A','Z') as $i) {
echo (array_key_exists ("$i", $alpha)) ? '<li><a href="#'.$i.'">'.$i.'</a></li>' : '<li>'.$i.'</li>';
}

echo '</ul><ol class="listfanart">';

// Create Data Listing
foreach($alpha as $i => $r) {
//	if (array_key_exists ("$i", $alpha)) {
	echo '<a name="'.$i.'"></a><h3>'.$i.'<div style="font-size: 10px; float: right;"><a href="#">top</a></h3>';
	foreach ($r as $records) {
		$url = $records['url'];
		$key = $records['author'];
		$value = $records['title'];
		echo '<li><a href="'.$url.'" target="_blank">'.$value.'</a> by '.$key.'</li>
';

	}
//	}
}

?> 

try...

 

That code actually greatly improved the previous snippet by allowing all ascii characters to be shown rather than just those which started with a letter.  Thanks a bunch for the improvement!

 

Now another question (hopefully my last): I have several rows which start with ascii characters such as plus signs (+), numbers, and colons.  Is there any way for me to group specified characters under a single symbol, such as the pound (#)?

 

Here's the new code as it now stands:

<?php

$sql = "SELECT *, UPPER(SUBSTRING(title,1,1)) AS letter FROM feudal WHERE `type` = 'Fanart' GROUP BY title, author ORDER BY title, author";
$query = mysql_query( $sql ) or die(mysql_error());

while ($records = @mysql_fetch_array ($query)) {
   $alpha[$records['letter']][] = $records;
}

echo '<ul class="alphabet">
<li><a href="#other">#</a></li>';

foreach(range('A','Z') as $i) {
echo (array_key_exists ("$i", $alpha)) ? '<li><a href="#'.$i.'">'.$i.'</a></li>' : '<li>'.$i.'</li>';
}

echo '</ul><ol class="listfanart">';

foreach($alpha as $i => $r) {
//   if (array_key_exists ("$i", $alpha)) {
      echo '<a name="'.$i.'"></a><h3>'.$i.'<div style="font-size: 10px; float: right;"><a href="#">top</a></h3>';

      foreach ($r as $records) {
         $url = $records['url'];
         $key = $records['author'];
         $value = $records['title'];
         echo '<li><a href="'.$url.'" target="_blank">'.$value.'</a> by '.$key.'</li>
';

}

}

?>

what do you mean by group?

 

Do you want an array called # to hold all those that start with # ?

 

What I'm aiming for is an array which lists all ascii characters which are not letters, and if a row happens to start with one of those characters they would be placed under a heading called #.  Here's an example:

 

table

:: title1 ::

title2

+ title3 +

 

and have the output be like this:

 

# | T

 

#

:: title1 ::

+ title3 +

 

T

title2

I lost you there, you wanna explain your main concept of what your trying to do and we can take it from the top? This solution seems very convoluted at this point and normally when you get there, its time to re think the foundation.  Provide a brief explanation of what you want to accomplish, and sample input and sample output. 

I lost you there, you wanna explain your main concept of what your trying to do and we can take it from the top? This solution seems very convoluted at this point and normally when you get there, its time to re think the foundation.  Provide a brief explanation of what you want to accomplish, and sample input and sample output. 

 

Your question may have lost me, but I'll rephrase my previous explanation while defining the entirety of the code. 

 

The current code takes all first characters for the titles and assigns them as headers for an ordered list (under the <h3> tag).  Then those titles which begin with that character are listed beneath the header character.  Here's a sample table:

 

table

:: title1 ::

title2

+ title3 +

2title

anothertitle

 

So the output currently looks like this:

 

<h3>:</h3>

:: title1 ::

 

<h3>+</h3>

+ title3 +

 

<h3>2</h3>

2title

 

<h3>A</h3>

anothertitle

 

<h3>T</h3>

title2

 

What I want, however, is for the titles which begin with characters that are not letters to be grouped into a single category (represented by the pound (#)), so the total output would instead look like this:

 

<h3>#</h3>

:: title1 ::

+ title3 +

2title

 

<h3>A</h3>

anothertitle

 

<h3>T</h3>

title2

 

Possibly some sort of array would work which listed the non-alphabetical characters and then an IF statement used in the final foreach to find those titles which started with non-alphabetical characters and grouped them under the pound (#) character, but I'm just guessing here.

 

And here's a slightly modified code (got rid of one now-useless line):

<?php

$sql = "SELECT *, UPPER(SUBSTRING(title,1,1)) AS letter FROM feudal WHERE `type` = 'Fanart' GROUP BY title, author ORDER BY title, author";
$query = mysql_query( $sql ) or die(mysql_error());

while ($records = @mysql_fetch_array ($query)) {
   $alpha[$records['letter']][] = $records;
}

echo '<ul class="alphabet">
<li><a href="#other">#</a></li>';

foreach(range('A','Z') as $i) {
echo (array_key_exists ("$i", $alpha)) ? '<li><a href="#'.$i.'">'.$i.'</a></li>' : '<li>'.$i.'</li>';
}

echo '</ul><ol class="listfanart">';

foreach($alpha as $i => $r) {

      echo '<a name="'.$i.'"></a><h3>'.$i.'<div style="font-size: 10px; float: right;"><a href="#">top</a></h3>';

      foreach ($r as $records) {
         $url = $records['url'];
         $key = $records['author'];
         $value = $records['title'];
         echo '<li><a href="'.$url.'" target="_blank">'.$value.'</a> by '.$key.'</li>
';

}
}
?>

this should help you figure out the rest (untested)

 


//mysql_fetch_array should give you an array like this

$array[0] = ":: title1 ::";
$array[1] = "title2";
$array[2] = "+ title3 +";
$array[3] = "2title";
$array[4] = "anothertitle";

$symbols = array();
foreach($array as $key => $value) {
$first = substr($value,1,1);
$match_symbols = '/[^a-z\d]+/';
if(preg_match($match_symbols,$first)) {
	// take this out of the original array and put it into the symbols array
	$symbols[] = array_slice($array,$key);
}
}

 

 

the idea is that you use regex to determine if the first char is a symbol, if it is, take it out of that array and into a special symbols array.  What you are left with is the original array without the symbols.  You can extend this by doing more regex's to fit your other groups.

 

Does this help?

<?php

$sql = "SELECT *, UPPER(SUBSTRING(title,1,1)) AS letter FROM feudal WHERE `type` = 'Fanart' GROUP BY title, author ORDER BY title";
$query = mysql_query( $sql ) or die(mysql_error());
$ranges = range('A', 'Z');
array_unshift($ranges, '#');
while ($records = @mysql_fetch_array ($query)) {
if (!in_array($records['letter'], $ranges)) $records['letter']='#';
$alpha[$records['letter']][] = $records;
//	${$records['letter']}[$records['author']] = $records['title'];

//	$url= $records['url'];
}

//echo '<ul class="alphabet">
//<li><a href="#other">#</a></li>';

// Create Alpha link Listing
foreach($ranges as $i) {
echo (array_key_exists ($i, $alpha)) ? '<li><a href="#'.$i.'">'.$i.'</a></li>' : '<li>'.$i.'</li>';
}

echo '</ul><ol class="listfanart">';

// Create Data Listing
foreach($alpha as $i => $r) {
//	if (array_key_exists ("$i", $alpha)) {
	echo '<a name="'.$i.'"></a><h3>'.$i.'<div style="font-size: 10px; float: right;"><a href="#">top</a></h3>';
	foreach ($r as $records) {
		$url = $records['url'];
		$key = $records['author'];
		$value = $records['title'];
		echo '<li><a href="'.$url.'" target="_blank">'.$value.'</a> by '.$key.'</li>
';

	}
//	}
}

?>  

this should help you figure out the rest (untested)

 


//mysql_fetch_array should give you an array like this

$array[0] = ":: title1 ::";
$array[1] = "title2";
$array[2] = "+ title3 +";
$array[3] = "2title";
$array[4] = "anothertitle";

$symbols = array();
foreach($array as $key => $value) {
$first = substr($value,1,1);
$match_symbols = '/[^a-z\d]+/';
if(preg_match($match_symbols,$first)) {
	// take this out of the original array and put it into the symbols array
	$symbols[] = array_slice($array,$key);
}
}

 

 

the idea is that you use regex to determine if the first char is a symbol, if it is, take it out of that array and into a special symbols array.  What you are left with is the original array without the symbols.  You can extend this by doing more regex's to fit your other groups.

 

Does this help?

 

Could you explain what the code is trying to do line by line?  I truly can't figure out how to integrate the new foreach into the current snippet because I'm not sure where to the place the small code.

 

// so you grab the data from mysql by word

$res = mysql_query("SELECT * FROM words");

 

// form an array out of that query

$array = mysql_fetch_array($res);

 

/* should look like this

$array[0] = ":: title1 ::";

$array[1] = "title2";

$array[2] = "+ title3 +";

$array[3] = "2title";

$array[4] = "anothertitle";

*/

 

// create a blank array to hold all the words that start with a symbol

$symbols = array();

 

// loop through every item in the array

// as you loop, $key = the index like 0,1,2 and $value = the word itself

foreach($array as $key => $value) {

 

        // get the first letter

$first = substr($value,1,1);

 

        // store the regex for matching symbols only

$match_symbols = '/[^a-z\d]+/';

 

        // if the first letter is a symbol

if(preg_match($match_symbols,$first)) {

 

// take this out of the original array and put it into the symbols array

$symbols[] = array_slice($array,$key);

}

}

I have many questions about the data.  They are in bold and are above the confusing area.  Most of them deal with the fact that the code appears to have no connection with, or may be different from, previous code snippets I've given.

 

 

Is this essentially what I've already given as $sql?

// so you grab the data from mysql by word

$res = mysql_query("SELECT * FROM words");

 

Should this connect to what I've already given as $query rather than $res?

// form an array out of that query

$array = mysql_fetch_array($res);

 

Can this be shortened to be less specific, like only listing those unusual first characters which need to be identified and separated?

/* should look like this

$array[0] = ":: title1 ::";

$array[1] = "title2";

$array[2] = "+ title3 +";

$array[3] = "2title";

$array[4] = "anothertitle";

*/

 

// create a blank array to hold all the words that start with a symbol

$symbols = array();

 

// loop through every item in the array

// as you loop, $key = the index like 0,1,2 and $value = the word itself

foreach($array as $key => $value) {

 

        // get the first letter

$first = substr($value,1,1);

 

Is there a "cheat sheet" for regex commands?  This appears to be gibberish to my limited knowledge.

        // store the regex for matching symbols only

$match_symbols = '/[^a-z\d]+/';

 

        // if the first letter is a symbol

if(preg_match($match_symbols,$first)) {

 

Now that we've put the specified rows into the $symbols array, what next?  Can I simply echo one of the stated fields ($array or $key) to create the output I've already created (example: <li><a href="'.$url.'" target="_blank">'.$value.'</a> by '.$key.'</li>) or is there something more which needs to be done?

// take this out of the original array and put it into the symbols array

$symbols[] = array_slice($array,$key);

}

}

 

The code also doesn't appear to group the now separated rows under the artificial character pound (#), which makes me wonder what heading they will be under in the fulling listing.  Can this simply be done by allowing $symbols to equal pound (#), or am I simplifying this too much?

I have many questions about the data.  They are in bold and are above the confusing area.  Most of them deal with the fact that the code appears to have no connection with, or may be different from, previous code snippets I've given.

 

 

Is this essentially what I've already given as $sql?

yes except this sql is less specific, im taking the first character in php not in the sql query

// so you grab the data from mysql by word

$res = mysql_query("SELECT * FROM words");

 

Should this connect to what I've already given as $query rather than $res?

yes, just make sure your output is correct

// form an array out of that query

$array = mysql_fetch_array($res);

 

Can this be shortened to be less specific, like only listing those unusual first characters which need to be identified and separated?

this is just sample, it should not appear as part of the final code, it is just what the sql query should give you

/* should look like this

$array[0] = ":: title1 ::";

$array[1] = "title2";

$array[2] = "+ title3 +";

$array[3] = "2title";

$array[4] = "anothertitle";

*/

 

// create a blank array to hold all the words that start with a symbol

$symbols = array();

 

// loop through every item in the array

// as you loop, $key = the index like 0,1,2 and $value = the word itself

foreach($array as $key => $value) {

 

        // get the first letter

$first = substr($value,1,1);

 

Is there a "cheat sheet" for regex commands?  This appears to be gibberish to my limited knowledge.

there is but ill explain what i wrote here

/*

all regex goes between '/regex here/'

[] = match inside the brackets

^ = not

a-z = match all letters from a to z

\d = match all digits

+ = match 1 or more of the previous

so in english

[^a-z\d]+ means match one or more of everything that is NOT a letter or number

in other words, match a symbol

*/

 

 

        // store the regex for matching symbols only

$match_symbols = '/[^a-z\d]+/';

 

        // if the first letter is a symbol

if(preg_match($match_symbols,$first)) {

 

Now that we've put the specified rows into the $symbols array, what next?  Can I simply echo one of the stated fields ($array or $key) to create the output I've already created (example: <li><a href="'.$url.'" target="_blank">'.$value.'</a> by '.$key.'</li>) or is there something more which needs to be done?

i don't know what you want to get as a final result, but to print out the values you need to loop through the symbols array or the other array to pull out their values. like to print out a list of all the words that begin with a symbol you would do this

foreach($symbol as $value) {

  echo "<li>".$value."</li>";

}

 

 

// take this out of the original array and put it into the symbols array

$symbols[] = array_slice($array,$key);

}

}

 

The code also doesn't appear to group the now separated rows under the artificial character pound (#), which makes me wonder what heading they will be under in the fulling listing.  Can this simply be done by allowing $symbols to equal pound (#), or am I simplifying this too much?

This thread is more than a year old. Please don't revive it unless you have something important to add.

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...

Important Information

We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue.