循环通过字母数组的A-Z索引

时间:2016-11-23 16:42:54

标签: php arrays sorting foreach while-loop

这已被问过几次,但没有一个例子用适当的HTML样式显示它。我在下面的代码中为每个部分包装<ul></ul>中的项目时遇到了一些麻烦。我的当前代码在切换字母之前无限循环while循环,我不知道如何正确地执行它。

这是我目前的代码:

$range = range('A', 'Z');
if (!empty($terms)) {
  foreach ($range as $letter) {
    echo '<div class="column">';
      echo '<h3>' . $letter . '</h3>';
      echo '<ul>';
      foreach ($terms as $term) {
        while (strtoupper(substr($term->name, 0, 1)) == $letter) {
          echo '<li><a href="' . home_url(get_term_link($term->term_id)) . '">' . $term->name  . '</a></li>';
        }
      }
      echo '</ul>';
    echo '</div>';
  }
}

预期产出:

<div class="column">
  <h3>A</h3>
  <ul>
    <li><a href="#">Atom</a></li>
    <li><a href="#">Awesome</a></li>
  </ul>
</div>

<div class="column">
   <h3>B</h3>
   <ul>
     <li><a href="#">Banana</a></li>
     <li><a href="#">Bottle</a></li>
   </ul>
</div>

<div class="column">
   <h3>C</h3>
   <p>No item found</p>
</div>

[...]

5 个答案:

答案 0 :(得分:0)

我刚刚完全更改了代码,因为它存在一些性能问题,主要由@RiggsFolly注意到,我同意。如果您想查看编辑历史记录中的旧代码。

if (!empty($terms)) {
  foreach($terms as $term){
    $data[strtoupper($term->name[0])][] = '<li><a href="' . home_url(get_term_link($term->term_id)) . '">' . $term->name  . '</a></li>';
  }

  foreach(range('A', 'Z') as $letter){
    echo '<div class="column">';
    echo '<h3>' . $letter . '</h3>';
    if(isset($data[$letter])){ 
      echo '<ul>' . implode('', $data[$letter]) . '</ul>';
    } else {
      echo '<p>No item found</p>';
    }
    echo '</div>';
  }
}

首先我们过滤掉数据,循环遍历每个术语名称,将其放在一个单独的数组中。这意味着我们将其整理一次,而不是做26次。这是基于每个键添加的,如果您没有匹配名称c,则永远不会设置$data['C']

现在进行第二次循环;既然你也希望显示没有结果的字母,我们将在字母表上循环而不是$ data,只有在密钥存在与否时才匹配,如果知道我们有数组结果。

答案 1 :(得分:0)

好友,你不需要在这里停留一段时间

我将其更改为IF

在这里

$range = range('A', 'Z');
if (!empty($terms)) {
foreach ($range as $letter) {
echo '<div class="column">';
  echo '<h3>' . $letter . '</h3>';
  echo '<ul>';
  foreach ($terms as $term) {
    if (strtoupper(substr($term->name, 0, 1)) == $letter) {
      echo '<li><a href="' . home_url(get_term_link($term->term_id)) . '">' . $term->name  . '</a></li>';
    }
  }
  echo '</ul>';
echo '</div>';
  }
}

答案 2 :(得分:-1)

您应该删除您处理的项目。如果没有,while循环是无限的。

while替换为if条件,输出应该与您想要的一样。

答案 3 :(得分:-1)

foreach ($terms as $term) {
  while (strtoupper(substr($term->name, 0, 1)) == $letter) {
    echo ...;
  }
}

会在while内循环,因为你不会在$terms数组中前进。

Actuall,你想要的只是 check ,如果这封信匹配,那么:

foreach ($terms as $term) {
  if (strtoupper(substr($term->name, 0, 1)) == $letter) {
    echo ...;
  }
}

会做到这一点。

旁注:这不是很有效,因为你循环遍历$range,然后对于那里的每个条目,你循环遍历$terms。一个更好的解决方案是,对您的术语进行排序,并且只循环一次。当它们被排序时,你就可以记住最后一个字母,如果它改变了,那么你就放了一个新的标题。

答案 4 :(得分:-1)

你去吧

<?php
  $terms = ["Ban","Asd","Adf","Banana"];
  sort($terms);
  $range = range('A', 'Z');
    foreach ($range as $letter) {
      echo '<div class="column">';
        echo '<h3>' . $letter . '</h3>';
        echo '<ul>';
        foreach ($terms as $index => $term) {
          if (strtoupper(substr($term, 0, 1)) == $letter) {
            echo '<li><a href="">' . $term  . '</a></li>';
            //so you would not run the same amount again
            unset($terms[$index]);
          } else {
            //break the loop when done with that letter
            break;
          }
        }
        echo '</ul>';
      echo '</div>';
    }
?>