Algorithm 循环迭代和打印开始和结束标记的标准模式

Algorithm 循环迭代和打印开始和结束标记的标准模式,algorithm,language-agnostic,design-patterns,Algorithm,Language Agnostic,Design Patterns,这是我以前遇到的一个问题,我还没有找到一个优雅的解决方案,所以我想我会寻求so的帮助 我正在迭代一个数组,并从该数组中打印出一些信息,但很难确定如何打印开始和结束标记。下面是一个示例表和所需的输出以及我当前算法的基本实现。我希望有人能给我指出一种更好的打印数据的算法。我正在用PHP做这件事,但是一个通用算法会很棒 非常感谢 表格:(为清晰起见增加了间距) 选项ID选项正文问题ID问题正文 ------------------------------------------------------

这是我以前遇到的一个问题,我还没有找到一个优雅的解决方案,所以我想我会寻求so的帮助

我正在迭代一个数组,并从该数组中打印出一些信息,但很难确定如何打印开始和结束标记。下面是一个示例表和所需的输出以及我当前算法的基本实现。我希望有人能给我指出一种更好的打印数据的算法。我正在用PHP做这件事,但是一个通用算法会很棒

非常感谢

表格:(为清晰起见增加了间距)

选项ID选项正文问题ID问题正文 --------------------------------------------------------------------- 是的,非常喜欢。你喜欢三明治吗? 你喜欢三明治吗? 一点也不喜欢你喜欢三明治吗? 我讨厌他们你喜欢三明治吗? 当然可以,你喜欢苹果吗? 是的,我想你喜欢苹果吗? 你喜欢苹果吗? 是的,非常喜欢。你喜欢薯条吗? 你喜欢薯条吗? 所需输出:

<div class='question' id='1'>
  <p>Do you like sandwiches?</p>

  <div class='choices'>
    <span class='choice'>Yes, very much</span>
    <span class='choice'>Somewhat</span>
    <span class='choice'>Not at all</span>
    <span class='choice'>I hate them</span>
  </div>
</div>

<div class='question' id='2'>
  <p>Do you like apples?</p>

  <div class='choices'>
    <span class='choice'>Sure, why not</span>
    <span class='choice'>Yeah, I guess</span>
    <span class='choice'>What are those</span>
  </div>
</div>

<div class='question' id='3'>
  <p>Do you like chips?</p>

  <div class='choices'>
    <span class='choice'>Yes, very much</span>
    <span class='choice'>Not at all</span>
  </div>
</div>
$last_id = null;
while ($choice = pg_fetch_array($choices)) {
    if ($last_id != $choice['id']) {
        if ($last_id != null) {
          echo "</div>";
        }

        echo "<div id='$choice[id]'>";
    }

    // Print choice info

    $last_id = $choice['id'];
}

if ($last_id != null) {
    echo "</div>";
}

你喜欢三明治吗

是的,非常喜欢 有点 一点也不 我讨厌他们 你喜欢苹果吗

当然,为什么不呢 是的,我想 那些是什么 你喜欢吃薯条吗

是的,非常喜欢 一点也不
我当前使用的基本算法:

<div class='question' id='1'>
  <p>Do you like sandwiches?</p>

  <div class='choices'>
    <span class='choice'>Yes, very much</span>
    <span class='choice'>Somewhat</span>
    <span class='choice'>Not at all</span>
    <span class='choice'>I hate them</span>
  </div>
</div>

<div class='question' id='2'>
  <p>Do you like apples?</p>

  <div class='choices'>
    <span class='choice'>Sure, why not</span>
    <span class='choice'>Yeah, I guess</span>
    <span class='choice'>What are those</span>
  </div>
</div>

<div class='question' id='3'>
  <p>Do you like chips?</p>

  <div class='choices'>
    <span class='choice'>Yes, very much</span>
    <span class='choice'>Not at all</span>
  </div>
</div>
$last_id = null;
while ($choice = pg_fetch_array($choices)) {
    if ($last_id != $choice['id']) {
        if ($last_id != null) {
          echo "</div>";
        }

        echo "<div id='$choice[id]'>";
    }

    // Print choice info

    $last_id = $choice['id'];
}

if ($last_id != null) {
    echo "</div>";
}
$last\u id=null;
而($choice=pg_fetch_数组($choices)){
如果($last_id!=$choice['id'])){
如果($last_id!=null){
回声“;
}
回声“;
}
//打印选择信息
$last_id=$choice['id'];
}
如果($last_id!=null){
回声“;
}
注意:我使用这种方法的原因是为了优化。这只需要一个数据库查询,将会有很多结果。我不想对每个问题都做一个查询来得到它的选择。我知道怎么做,而且很简单,但效率不高,速度也不快


编辑1:修复了代码,算法现在可以工作了,但仍然不太漂亮。对于评论者:
pg_fetch_array()
是一个PostgreSQL函数,基本上创建一个关联数组。与物体非常相似。允许您只要求输入
$choice['id']
$choice['body']

如果新读取的id与上一个不同(且最后一个id不为空),则应在循环开始时打印结束的


此外,在循环之后(同样,如果last id不为null,这意味着根本没有组),您需要关闭最后一个组。

我已经有一段时间没有做任何PHP了,但我会尝试类似的方法

// print leading div for very first in array
echo "<div>";

$last_question = null;
while ($choice = pg_fetch_array($choices)) {

    // print choice info
    echo "<span ...>";

    if($last_question != $choice['question_id'])
    {
        // print trailing div for last one
        echo "</div>";

        // print leading div for next one
        echo "<div>";
    }


    // set last question
    $last_question = $choice['question_id'];

}

// print trailing div for very last in array
echo "</div>";
//打印数组中第一个的前导div
回声“;
$last_question=null;
而($choice=pg_fetch_数组($choices)){
//打印选择信息
回声“;
如果($last_question!=$choice['question_id']))
{
//打印最后一个的尾随div
回声“;
//打印下一个的前导div
回声“;
}
//设定最后一个问题
$last_question=$choice['question_id'];
}
//打印数组中最后一个的尾随div
回声“;

可能需要改进,以确保它不会在末尾打印额外的div。

按类似值对项目进行分组很难被称为算法。它更像是一种编码模式

编写代码的一个好方法是将机制与意图分开。在这种情况下,机制是如何跟踪键值以找到分组边界,目的是为每个顺序组输出HTML

例如,Python有一个名为groupby的库函数来实现这一点。因此,在Python中,代码看起来像这样(忽略使用模板库的事实):

这将是您在中包含的典型库代码。然后,处理输出的代码变得相当琐碎。与分组方式完全隔离。例如,您可以更改array_groupby以返回一个实现迭代器接口的对象,并且只从输入iterable延迟获取

$questions = array_groupby(pg_fetch_array($choices),
    function($choice) { return $choice['id']; });

foreach ($questions as $choices) {
    $question = $choices[0];
    echo '<div class="question" id="'.$question['id'].'">';
    echo '<p>'.$question['body'].'</p>';
    echo '<div class="choices">';
    foreach ($choices as $choice) {
        echo '<span class="choice">'.$choice['choice_body'].'</span>';
    }
    echo '</div>';
    echo '</div>';
}
$questions=array\u groupby(pg\u fetch\u array($choices),
函数($choice){return$choice['id'];});
foreach($问题作为$选项){
$question=$choices[0];
回声';
回音“”.$question['body']。

”; 回声'; foreach($choice作为$choice){ 回显'.$choice['choice_body'].'; } 回声'; 回声'; }

本例使用PHP5.3闭包特性。在较旧的版本中,指定提取分组键的函数会有点难看,可能需要面向对象的方法。

Hi您能解释一下pg\u fetch\u数组吗?很久以前我用过PHP,所以我不太了解上下文。在文章末尾添加了一些关于它的信息:-)你需要在循环后关闭
-查看我的答案。谢谢!我实际上是这样做的,只是在打印之前我没有检查$last_id是否为空。我会更新代码。你知道更好的解决方法吗?不知道-我相信这是标准的方法。您可以通过将这些内容放入诸如
groupstart()
groupend()
之类的函数中,并在循环中调用这些函数来减少代码重复(将div打印两次)。这实际上并不比我现有的解决方案好多少。更不用说,第一次
打印必须在循环内部,以便我可以打印t的id
$questions = array_groupby(pg_fetch_array($choices),
    function($choice) { return $choice['id']; });

foreach ($questions as $choices) {
    $question = $choices[0];
    echo '<div class="question" id="'.$question['id'].'">';
    echo '<p>'.$question['body'].'</p>';
    echo '<div class="choices">';
    foreach ($choices as $choice) {
        echo '<span class="choice">'.$choice['choice_body'].'</span>';
    }
    echo '</div>';
    echo '</div>';
}