我有一系列状态,我想要做的是按首字母对它们进行分类,然后显示这些组。我几乎正常工作,最后一个问题是:
我希望所有状态都在逗号分隔的单个框中,而不是每个状态都在它自己的灰色框中。这是我的代码:
<?
$lastChar = '';
sort($state_list, SORT_STRING | SORT_FLAG_CASE);
foreach ($state_list as $state) {
$char = $state[0];
echo "<div class=\"stateTable\">";
if ($char !== $lastChar) {
echo "<div class=\"stateTopRow\">" . strtoupper($char) . "</div>";
echo "<div class=\"clear\"></div>";
$lastChar = $char;
}
echo "<div class=\"stateBody\">" . $state . "</div>";
echo "<div class=\"clear\"></div>";
echo "</div>";
}
?>
问题在于它为每个单独的状态循环整个stateBody div。我试过在if语句中以某种方式包括stateBody,但这完全打破了样式(并且理所当然)。
有没有办法在if语句中包含stateBody,然后添加另一个foreach来循环通过相应的状态?谢谢!
答案 0 :(得分:5)
我会建议采用略有不同的方法。由于您最终希望将它们全部分组,因此最好通过相应地组织阵列来开始。循环遍历它,并创建一个新数组,其子数组由第一个字母索引。在迭代原始数组时,在适当字符的索引处追加到新数组。然后,为您的输出循环更容易。
通常最好将数据格式化为最终需要的结构,以便稍后简化输出逻辑。
// Start by sorting as you already did
sort($state_list, SORT_STRING | SORT_FLAG_CASE);
// Create a new array
$output_array = array();
// Loop over the one you have...
foreach ($state_list as $state) {
$first = strtoupper($state[0]);
// Create the sub-array if it doesn't exist
if (!isset($output_array[$first])) {
$ouput_array[$first] = array();
}
// Then append the state onto it
$output_array[$first][] = $state;
}
结果数组如下所示:
Array
(
[A] => Array
(
[0] => Alabama
[1] => Arkansas
[2] => Alaska
)
[C] => Array
(
[0] => Connecticut
)
)
现在你需要一个简单的循环和一个implode()
来产生你的输出:
// For clarity, I omitted your surrounding <div> markup
// this is just the first letter and the state lists...
foreach($output_array as $state_index => $states) {
// The index is the first letter...
echo "<div class='stateTopRow'>$state_index</div>";
// And the sub-array can be joined with implode()
echo "<div class='stateBody'>" . implode(', ', $states) . "</div>";
}
答案 1 :(得分:0)
<?
$lastChar = '';
sort($state_list, SORT_STRING | SORT_FLAG_CASE);
$cnt = 0;
echo "<div class=\"stateTable\">";
foreach ($state_list as $state) {
$char = $state[0];
if ($char !== $lastChar) {
if (($char !== 'a') && ($char !== 'A')) {
echo "</div><div class=\"clear\"></div>"; // close off last state list
}
echo "<div class=\"stateTopRow\">" . strtoupper($char) . "</div>";
echo "<div class=\"clear\"></div>";
$lastChar = $char;
$cnt = 0;
}
if ($cnt == 0) {
echo "<div class=\"stateBody\">" . $state;
} else {
echo ", " . $state;
}
$cnt++;
}
echo "</div>";
?>
答案 2 :(得分:0)
$lastChar = '';
sort($state_list, SORT_STRING | SORT_FLAG_CASE);
echo "<div class='stateTable'>";
foreach ($state_list as $state)
{
$char = $state[0];
if ($char != $lastChar)
{
if ($lastChar != '')
echo "</div><div class='clear' />"; // close previous state list
$lastChar = $char;
echo "<div class='stateTopRow'>" . strtoupper($char) . "</div>";
echo "<div class='stateBody'>$state"; // open new state list
}
else // next state name
{
echo ", $state";
}
}
echo "</div><div class='clear' />"; // close last list
echo "</div>"; // close whole table
正如另一位评论者所说,混合输出和数据组织很少是一个好的理念 看看你把问题分开后会变得多么简单:
// sort all states alphabetically
sort($state_list, SORT_STRING | SORT_FLAG_CASE);
// split names according to their initial
foreach ($state_list as $state)
$alpha_table[$state[0]][] = $state;
// output each letter group
foreach ($alpha_table as $letter => $list)
{
echo "<div class='stateTopRow'>".strtoupper($letter) ."</div>". // header
"<div class='stateBody'>" .implode (",", $list)."</div>". // list
"<div class='clear' />"; // separator
}
答案 3 :(得分:0)
如果要将所有内容保存在一次扫描中(性能方面),我建议如下:
<?
$lastChar = '';
sort($state_list, SORT_STRING | SORT_FLAG_CASE);
foreach ($state_list as $state) {
$char = $state[0];
$states_arr = array();
echo "<div class=\"stateTable\">";
if ($char !== $lastChar) {
echo "<div class=\"stateTopRow\">" . strtoupper($char) . "</div>";
echo "<div class=\"clear\"></div>";
//if not the first letter
if ($lastChar) {
echo "</div>";//end the stateDiv div
echo implode($states_arr,', ');//print the states with commas
}
//open the stateBody div
echo "<div class=\"stateBody\">";
$lastChar = $char;
}
//add state to the array but don't print yet
$states_arr[] = $state;
echo "<div class=\"clear\"></div>";
echo "</div>";
}
?>
如果性能不是一个因素,您可能希望实际运行2次扫描 - 第一次扫描组织数据,第二次扫描显示数据。
但是,上述方法应该按照您的要求运作。
希望这有帮助!
答案 4 :(得分:0)
<?php
$state_list= array("alabama", "alaska", "arkansas");
$lastChar = '';
sort($state_list, SORT_STRING | SORT_FLAG_CASE);
foreach ($state_list as $state) {
$char = $state[0];
echo "<div>";
echo "<div class=\"stateTable\">";
if ($char !== $lastChar) {
echo "<div class=\"stateTopRow\">" . strtoupper($char) ."</div>";
echo "<div class=\"clear\"></div>";
$lastChar = $char;
}
}
$states= implode(",", $state_list);
echo $states;
?>