PHP-简单嵌套无序列表(UL)数组 [英] PHP - Simple Nested Unordered List (UL) Array

查看:90
本文介绍了PHP-简单嵌套无序列表(UL)数组的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在stackoverflow上看到了这个嵌套的UL数组问题的一些变体,但是我认为我的方法比其他方法更简单.我正在寻找一个简单的数组循环,该循环允许允许无限量的主题(父母)和无限量的项目(儿童),例如:

I have seen a few variants of this nested UL array question on stackoverflow, but I think mine is simpler than the others. I am looking for a simple array loop that allows allows for an infinite amount of topics (parents) with an infinite amount of items (children), like:

<ul>
    <li>Topic</li>
        <ul>
            <li>Item</li>
            <li>Item</li>
            <li>Item</li>
            <li>Item</li>
        </ul>
</ul>

我尝试使用以下代码进行此操作:

I have attempted this with the following code:

<?php
$result = mysql_query("SELECT * FROM News");

$topicname = false;

while($row = mysql_fetch_array($result)) {
    if (!$row['TopicID']) {
            $row['TopicName'] = 'Sort Me';
    }
    if ($topicname != $row['TopicName']) {
        echo '<ul><li>' . $row['TopicName'] . '</li><ul>';
        $topicname = $row['TopicName'];
    }
    echo '';
    echo '<li>' . $row['NewsID'] . '"</li>';
    echo '';
}
if ($topicname != $row['TopicName']) {
    echo '</ul>';
    $topicname = $row['TopicName'];
}   
?>

上面的代码呈现以下内容:

The above code renders the following:

* Topic A
      o News 1
      o News ...
      o News 51000
            + Topic B
                  # News 1
                  # News ...
                  # News 51000
                        * Topic C
                              o News 1
                              o News ...
                              o News 51000
                                    + Topic D
                                          # News 1
                                          # News ...
                                          # News 51000

该代码希望呈现以下内容:

The would like the code to render the following:

* Topic A
      o News 1
      o News ...
      o News 51000
* Topic B
      o News 1
      o News ...
      o News 51000
* Topic C
      o News 1
      o News ...
      o News 51000
* Topic D
      o News 1
      o News ...
      o News 51000

任何想法将不胜感激!

商标解决的问题;有可能解决这个相关问题吗?

马克:是的,这成功了!非常有帮助,谢谢.我想知道您是否能够帮助我将其提高到另一个层次.如果您认为在此问题内提出问题不适当,请告诉我,我将单独询问,但是您的代码是可靠的,因此我想我会继续进行下去.

Hi Mark: Yes, this did the trick! Very helpful, thank you. I was wondering if you might be able to help me take this to another level of sophistication. If you think it is not appopriate to ask within this question, let me know and I will ask separately, but your code is solid, so I thought I would follow up with it.

使用与上面相同的代码,我希望通过选择1列,2列,3列,4列,5列等(最多10个)为用户提供查看数据的选项.数据行将分为单独的DIV标签,行数将包括主题和新闻项.我将使用CSS控制DIV标签,但我希望将行计数平均分配到指定数量的列的DIV标签中.我希望孩子们的新闻项目不要与他们的父母分开,并尽可能地与他们分开.如果有一个断点,其中一列可以长于另一列并且是偶数/任意数,则优先级将移到最左列,例如:此小插图:

Using the same code above, I am hoping to give the user the option to view the data via the choice of 1 column, 2 columns, 3 columns, 4 columns, 5 columns, etc. (up to 10). The rows of data would be divided into separate DIV tags and the row count would include both the topics and the news items. I will control the DIV tags with my CSS, but I would like to group the row count evenly into DIV tags for the specified amount of columns. I would like the children news items to not be separated from their parent and the groups to be as even as possible. If there is a breaking point where 1 column can be longer than the other and it's even/arbitrary, precedence would go to the left-most column, like: this mini-illustration:

XXX
XX
X

我不知道这有多清楚,所以这里有一个例子.如果用户选择1列,他们将看到以下30个行"数据:

I don't know how clear this is, so here is an example. If the user chooses 1 column, they would see the following 30 "rows" of data:

<div id="Columns1Group1of1">
* Topic A
      o News 1
      o News 2
      o News 3
* Topic B
      o News 1
      o News 2
      o News 3
      o News 4
* Topic C
      o News 1
      o News 2
      o News 3
      o News 4
      o News 5
* Topic D
      o News 1
      o News 2
      o News 3
* Topic E
      o News 1
      o News 2
      o News 3
      o News 4
* Topic F
      o News 1
      o News 2
      o News 3
      o News 4
      o News 5
</div>

如果用户选择2列,他们将看到以下30个行"数据分成2组,每组都包裹着DIV标签.碰巧,这恰好可以很好地隔开空间:

If the user chooses 2 columns, they would see the following 30 "rows" of data divided into 2 groups with DIV tags wrapped around each. This happens to space out nicely by coincidence:

<div id="Columns2Group1of2">        <div id="Columns2Group2of2">
* Topic A                           * Topic D
      o News 1                          o News 1
      o News 2                          o News 2
      o News 3                          o News 3
* Topic B                           * Topic E
      o News 1                          o News 1
      o News 2                          o News 2
      o News 3                          o News 3
      o News 4                          o News 4
* Topic C                           * Topic F
      o News 1                          o News 1
      o News 2                          o News 2
      o News 3                          o News 3
      o News 4                          o News 4
      o News 5                          o News 5
</div>                              </div>

如果用户选择3列,他们将看到以下30行数据分成3组,每组都包裹着DIV标签.间隔开始变得棘手,我愿意提出建议.

If the user chooses 3 columns, they would see the following 30 "rows" of data divided into 3 groups with DIV tags wrapped around each. The spacing is starting to get tricky and I am open to suggestions.

<div id="Columns3Group1of3">        <div id="Columns3Group2of3">        <div id="Columns3Group3of3">
* Topic A                           * Topic C                           * Topic E
      o News 1                          o News 1                            o News 1
      o News 2                          o News 2                            o News 2
      o News 3                          o News 3                            o News 3
* Topic B                               o News 4                            o News 4
      o News 1                          o News 5                        * Topic F
      o News 2                      * Topic D                               o News 1
      o News 3                          o News 1                            o News 2
      o News 4                          o News 2                            o News 3
</div>                                  o News 3                            o News 4
                                    </div>                                  o News 5
                                                                        </div>

如果用户选择4列,他们将看到以下30个行"数据分成4组,每组都包裹着DIV标签.再说一次,我什至不知道该如何为插图手动放置空格,但是对于孩子来说,留在父母的陪伴下很重要.

If the user chooses 4 columns, they would see the following 30 "rows" of data divided into 4 groups with DIV tags wrapped around each. Again, I don't even know how to manually space it for my illustration, but it is important for the children to stay under the parent.

<div id="Columns4Group1of4">        <div id="Columns4Group2of4">        <div id="Columns4Group3of4">        <div id="Columns4Group4of4">
* Topic A                           * Topic C                           * Topic D                           * Topic F
      o News 1                        o News 1                            o News 1                            o News 1
      o News 2                        o News 2                            o News 2                            o News 2
      o News 3                        o News 3                            o News 3                            o News 3
* Topic B                             o News 4                          * Topic E                             o News 4
      o News 1                        o News 5                            o News 1                            o News 5
      o News 2                      </div>                                o News 2                          </div>
      o News 3                                                            o News 3
      o News 4                                                            o News 4
</div>                                                                  </div>

推荐答案

这应该可以解决问题:

$result = mysql_query("SELECT * FROM News");
$topicname = '';

// open list of topics
echo '<ul>';

// loop through topics
while($row = mysql_fetch_array($result)) {
    if (!$row['TopicID']) {
        // fake topic name for unsorted stuff
        $row['TopicName'] = 'Sort Me';
    }
    if ($topicname != $row['TopicName']) {
        if($topicname != ''){
            // had a topic name, means we opened a list
            // that hasn't been closed, close it.
            echo '</ul>';
        }
        // print this topic and open the list of articles
        echo '<li>' . $row['TopicName'] . '</li><ul>';
        // update the current topic to be this TopicName
        $topicname = $row['TopicName']; 
    }
    // the news item
    echo '<li>' . $row['NewsID'] . '"</li>';
}
if($topicname != ''){
    // we saw at least one TopicName, we need to close
    // the last open list.
    echo '</ul>';
}
// end topic list
echo '</ul>';

我认为您的真正问题是您每次都打开两个列表,但是只关闭一个列表(甚至移动列表中的最后一个块).

I think your real problem is that you were opening two lists each time, but only closing one (even moving the last block inside the list).

(新问题)的第二部分:

For the second part of your (new) question:

对于较大的列表(例如300多个项目),我要做出的权衡是我在将列表存储在内存中并进行两次迭代(而不是仅查询所需的计数)时所做出的权衡.也就是说,下面的解决方案将所有内容都存储到内存中,然后进行第二次迭代以将其打印出来.一种替代方法是运行两个查询,一个查询找到唯一主题名称的数量,另一个查询列表中总项目的数量.

I'll caveat that for larger lists (say, more than 300 items) the tradeoff I'm making with respect to storing the list in memory and iterating twice rather than just querying for counts needed would swing the other way. That is, the solution below puts everything into memory, then iterates a second time to print it out; an alternative would be to run two queries, one to find the number of unique TopicNames and one to find the number of total items in the list.

此外,对于显示,您真的想解决一些布局优化问题,我会天真地做一下,每列仅使(大约)相等的主题数,并且当该划分不起作用时,这将朝着左边.您将看到可以在其中进行调整或替换一些代码以获得不同(更好的结果)的地方.

Also, for display, you really want to solve some optimization for layout, I'll do this naively and just make a (roughly) equal number of topics per column and when the division doesn't work out this will weight towards the left. You'll see where you can tweak or replace some code to get different (and better?) results.

$columns = // user specified;

$result = mysql_query("SELECT * FROM News");
$num_articles = 0;

// $dataset will contain array( 'Topic1' => array('News 1', 'News2'), ... )
$dataset = array();
while($row = mysql_fetch_array($result)) {
    if (!$row['TopicID']) {
        $row['TopicName'] = 'Sort Me';
    }
    $dataset[$row['TopicName']][] = $row['NewsID'];
    $num_articles++;
}

$num_topics = count($dataset);

// naive topics to column allocation
$topics_per_column = ceil($num_topics / $columns);

$i = 0; // keeps track of number of topics printed
$c = 1; // keeps track of columns printed
foreach($dataset as $topic => $items){
    if($i % $topics_per_columnn == 0){
        if($i > 0){
            echo '</ul></div>';
        }
        echo '<div class="Columns' . $columns . 'Group' . $c . '"><ul>';
        $c++;
    }
    echo '<li>' . $topic . '</li>';
    // this lists the articles under this topic
    echo '<ul>';
    foreach($items as $article){
        echo '<li>' . $article . '</li>';
    }
    echo '</ul>';
    $i++;
}
if($i > 0){
    // saw at least one topic, need to close the list.
    echo '</ul></div>';
}

这篇关于PHP-简单嵌套无序列表(UL)数组的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆