Find the number of leaves for each parent ul in the nested ul structure

Given an html structure that looks like the next html but has arbitrary depth. (i.e., it can go many levels deeper). Since it has an arbitrage depth, I would prefer a solution that does not require the addition of additional markup in html (e.g. classes)

<ul><!-- Leaf Count 3 -->
  <li>branch 1
    <ul><!-- Leaf Count 2 -->
      <li>leaf 1</li>
      <li>leaf 2</li>
    </ul>
  </li>
  <li>leaf 3</li>
</ul>

How can I count all the leaves that are children for each ul? Thus, in this example, the outermost ul would have 3 sheets and two sheets nested. This seems like a recursion problem, but I can't think it through.

+6
source share
5 answers

, . .

jquery simple selectee li:not(:has(*)). li, (leaf node).

$("#dvMain").find('ul').each, ul, .

$(document).ready(function() {
    $("#dvMain").find('ul').each(function(item) {
        console.log($(this).find('li:not(:has(*))').length);
    });
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>

<div id="dvMain">
<ul><!-- Leaf Count 4 -->
  <li>branch 1
    <ul><!-- Leaf Count 2 -->
      <li>leaf 1</li>
      <li>leaf 2</li>
    </ul>
  </li>
  <li>branch 1
    <ul><!-- Leaf Count 1 -->
      <li>leaf 1</li>
    </ul>
  </li>
  <li>leaf 3</li>
</ul>
</div>
Hide result
+4

HTML, jQuery filter:

function filterLeaf(ele) {
  if ($(ele).children().length === 0) {
    return true;
  }
  return false;
}

var nouter = $('#outer').find('li').filter(function() {
  return filterLeaf(this);
}).length;
var ninner = $('#inner').find('li').filter(function() {
  return filterLeaf(this);
}).length;
console.log(nouter);
console.log(ninner);
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>

<ul id="outer"><!-- Leaf Count 3 -->
  <li>branch 1
    <ul id="inner"><!-- Leaf Count 2 -->
      <li>leaf 1</li>
      <li>leaf 2</li>
    </ul>
  </li>
  <li>leaf 3</li>
</ul>
Hide result

, HTML, , "" leaf, jQuery .find:

var nouter = $('#outer').find('.leaf').length;
var ninner = $('#inner').find('.leaf').length;
console.log(nouter);
console.log(ninner);
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<ul id="outer"><!-- Leaf Count 3 -->
  <li>branch 1
    <ul id="inner"><!-- Leaf Count 2 -->
      <li class="leaf">leaf 1</li>
      <li class="leaf">leaf 2</li>
    </ul>
  </li>
  <li class="leaf">leaf 3</li>
</ul>
Hide result
+1

console.log($("ul.outer>li").length)
console.log($("ul.inner>li").length)
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<ul class='outer'><!-- Leaf Count 3 -->
  <li>branch 1
    <ul class="inner"><!-- Leaf Count 2 -->
      <li>leaf 1</li>
      <li>leaf 2</li>
    </ul>
  </li>
  <li>leaf 3</li>
</ul>
Hide result
  • >
0

TreeWalker api <ul>, .

const treeWalker = document.createTreeWalker(
  document.body,
  NodeFilter.SHOW_ELEMENT
);

const result = [];

while (treeWalker.nextNode()) {
  const node = treeWalker.currentNode;

  if (node.nodeName === 'UL') {
    result.push([...node.querySelectorAll('li')].filter((node) => !node.children.length).length);
  }
};

console.log(result);
<ul>
  <!-- Leaf Count 7 -->
  <li>branch 1
    <ul>
      <!-- Leaf Count 6 -->
      <li>leaf 1</li>
      <li>leaf 2</li>
      <li>branch 2
        <ul>
          <!-- Leaf Count 2 -->
          <li>leaf 1</li>
          <li>leaf 2</li>
        </ul>
      </li>
      <li>branch 3
        <ul>
          <!-- Leaf Count 2 -->
          <li>leaf 1</li>
          <li>leaf 2</li>
        </ul>
      </li>
    </ul>
  </li>
  <li>leaf 3</li>
</ul>
Hide result
0

You can use even this

$('ul').each(function(a){
count = 0;
$(this).find('li').each(function(){
if($(this).children().length ==0){
count++;
}

});
console.log(' ul level '+a+' count : '+count);

});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<ul><!-- Leaf Count 3 -->
  <li>branch 1
    <ul><!-- Leaf Count 2 -->
      <li>leaf 1</li>
      <li>leaf 2</li>
    </ul>
  </li>
  <li>leaf 3</li>
</ul>
Run codeHide result

Working demo

0
source

All Articles