【问题标题】:Break loop after every third iteration每第三次迭代后中断循环
【发布时间】:2016-10-30 07:35:07
【问题描述】:

我有一个数组arr = [1, 2, 3, 4]

我要打印

<ul>
  <li>1</li>
  <li>2</li>
  <li>3</li>
</ul>
<ul>
  <li>4</li>
</ul>

所以我需要在每个第三个元素之后中断循环。

let s = '<ul>';
arr.forEach(el => {
  s += '<li>' + el + '</li>';
});
s += '</ul>';

【问题讨论】:

  • 可以通过嵌套循环解决,即循环中的循环。
  • 你确定是reactjs吗?
  • 不能通过使用forEach来打破循环。请改用forwhile

标签: javascript arrays loops reactjs


【解决方案1】:

您可以将数组拆分成块并相应地创建您的 HTMLString,而不是打破循环。

var arr = [1, 2, 3, 4, 5];

function getULStructure(arr) {
  let s = '<ul>';
  arr.forEach(el => {
    s += '<li>' + el + '</li>';
  });
  s += '</ul>';
  return s
}

function createHTMLString(arr, count) {
  var _htmlString = ''
  while (arr.length > 0) {
    _htmlString += getULStructure(arr.splice(0, count))
  }
  return _htmlString
}

var _html = createHTMLString(arr, 3);
document.querySelector('.content').innerHTML = _html
<div class="content">
</div>

【讨论】:

  • 太复杂了。只需for (let i = 0; i &lt; arr.length; i++) { if (i === 3) {} }
  • @TânNguyễn 注意:“每个第三个元素”
  • @TânNguyễn 这是更加模块化的。您可以重用getULStructure 来获取任意数字的动态ul 列表。但是如果你想得到具体的计数,可以使用createHTMLString
  • arr[3] 将分配给第四个元素。如果if (i === 3),则创建新的&lt;ul/&gt;标签并添加到字符串中,否则,继续创建&lt;li/&gt;标签。
  • @TânNguyễn 这两种方法都很好。不同之处在于,在您的方法中,您必须硬编码或修补 3 来处理案例。在这里,我已将非依赖部分导出到外部函数。所以有一个关注点分离。一个函数将负责创建uls,而另一个函数将负责控制部分。同样,两者都很好。这只是个人选择。
【解决方案2】:

检查这个简单的解决方案,它使用没有任何中断语句的单个循环来创建您想要的 HTML 内容。

function generateTemplate(items, splitPoint) {
  var template = '<ul>';

  for (var i = 0; i < items.length; i++) {
    if (items[i] === splitPoint) {
      template += '</ul><ul>';
    }

    template += '<li>' + items[i] + '</li>';
  }

  template += '</ul>';

  return template;
}

var container = document.getElementById('container');
var items = [1, 2, 3, 4, 5, 6];
var template = generateTemplate(items, 4);
container.innerHTML = template;
ul {
  list-style-type: none;
  padding: 0px;
}
ul li {
  background-color: #E6E6E6;
  margin: 5px;
  padding: 5px;
}
<div id="container">
</div>

【讨论】:

    【解决方案3】:

    您可以使用这个简单的解决方案。

    这使用slice提取前3个元素并运行递归调用直到数组完成

    var a = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16]
    
    
    
    const itrate = (arr) => {
      var firstThree = arr.slice(0, 3)
      var rest = arr.slice(3, arr.length)
      var ul = document.createElement('ul')
      firstThree.forEach((el) => {
        if (el) {
          li = document.createElement('li')
          li.innerHTML = el
          ul.appendChild(li)
        }
      })
      var node = document.getElementById('app')
      node.appendChild(ul)
      if (rest.length > 0)
        itrate(rest)
    }
    
    itrate(a)
    &lt;div id="app"&gt;&lt;/div&gt;

    【讨论】:

      【解决方案4】:

      您只能在使用 forwhile 循环时进行 break 迭代,它们是标准的 javascript 迭代方式。

      顺便说一句,如果您想对数组进行模板化,在我看来,Array.prototype.reduce 是适合您想要的最佳方式...

      /**
       * @param {any[]} list
       * @param {int} breakIndex
      **/
      function compileHtmlLists(list, breakIndex) {
        
        return list
          .reduce(function(tpl, item, i, list) {
            var last = i === list.length - 1;
          
            item = "<li>" + item + "</li>";
          
            if(i === breakIndex) {
              item = "</ul><ul>" + item;        
            }
          
            if(last) {
              item += "</ul>";        
            }
          
          
            return tpl.concat(item);
          }, "<ul>")
        ;
      }
      
      var view = compileHtmlLists(
        [0, 1, 2, 3, 4, 5, 6, 7, 8, 9],
        5
      )
      
      console.log(view);

      【讨论】:

      • 我也更喜欢reduce,但是项目的数量可能会有所不同,所以我认为这个解决方案行不通
      • 如果您需要在某个(变量)点打破列表,可以通过 reduce...