foreach inside a foreach, can i be more efficient?
I have an array of letters that are used to create a header and sort an array of listItems from my database. What i have right now is:
$alph = 开发者_如何转开发array('a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z');
foreach($alph as $data) {
echo "<h3 id=" . $data .">" . $data . "</h3><br />";
foreach($list as $listItem) {
if(strtolower(substr($listItem->title, 0, 1)) === $data) {
echo $listItem;
}
}
}
This works great but I feel there may be improvements that can be made to increase speed.
You should loop through the array with the longest index first, in most languages the outer loop index increases the quickest.
Also there is no need to loop through the headers as long as each item knows what type of header it should have.
- Sort your items according to their header
- Loop through your items and check the header type of each item
- If no header of that type has been added yet, then add it before adding the item.
Sort $list before you start. That way you get the effiency of the implemented sorting algorithm (in PHP, it's quicksort, which performs a lot better than your current solution).
function my_sort($a, $b) {
return strcmp(strtolower($a->title), strtolower($b->title));
}
usort($list, 'my_sort');
Single loop, and more flexible first-character logic:
sort( $list );
$lastChar = '';
for ( $i = 0; $i < count( $list ); $i++ )
{
$char = strtolower( substr( $list[$i], 0, 1 ) );
if ( $char != $lastChar )
{
echo "<h3 id=" . $char .">" . $char . "</h3><br />";
$lastChar = $char;
}
echo $list[$i];
}
Solution that is O(n) i think, but cheats with php hash arrays:
// create empty index
$index = array_fill_keys(range('a', 'z'), array());
// index items by first letter
foreach ($list as $it) {
$index[strtolower(substr($it->title, 0, 1))][] = $it;
}
// print all
foreach ($index as $letter => $items) {
echo "<h3 id='$letter'>$letter</h3>";
foreach ($items as $it) {
echo $it;
}
}
精彩评论