Intersection of two collections of nodes with jQuery

2

I was trying to create a pseudo-search function by filtering Hugo's Taxonomy results does does recursion across all nodes, or rather, terms related to each other, something like this:

|-\ Category 1
  |-\ Subcategory 1
    |-\ Item 1
    |-\ Item 2
    |-\ Item 3
|-\ Category 2
  |-\ Item 1
    |-\ Category 1
      |-\ Subcategory
  |-\ Item 2
    |-\ Category 1
      |-\ Subcategory
  |-\ Item 3
    |-\ Category 1
      |-\ Subcategory

In fact, it returns something like this:

|-\ Category 1
  |-\ Subcategory 1
    |-\ Item 1
    |-\ Item 2
    |-\ Item 3
|-\ Category 2
  |-\ Subcategory 2
    |-\ Item 1
    |-\ Item 2
  |-\ Subcategory 3
    |-\ Item 3

With this in mind, I added data attributes to all <li> so I could get the nodes that match each chosen condition in a dropdown individually:

$( document ).ready( function() {
  
  /**
   * Aqui seria, na verdade, jQuery.val() sobre os menus dropdwn existentes
   */
  var c1   = 'category 1';
  var c2   = 'category 2';

  var nodes = $( '#taxonomy' );
  
  var terms  = [];

  $.each( nodes.find( 'ul li' ), function() {
      
    var term = $( this ).attr( 'data-term' );

    // Filtrando termos desnecessários
    
    if( $.inArray( term, [ 'category 1', 'category 2', 'subcategory 1', 'subcategory 2', 'subcategory 3' ] ) == -1 ) {
      terms.push( term );
    }
    
  });

  /**
   * As linhas a seguir, na verdade, estão condicionadas ao valor do dropdown
   * manualmente setado acima não ser o valor padrão, caso no qual não haveria filtragem
   */
  var category1 = [];

  $.each( nodes.find( 'li[data-term="' + c1 + '"] ul li' ), function() {
    category1.push( $( this ).attr( 'data-term' ) );
  });
  
  terms = $( terms ).filter( category1 );
  
  /**
   * Assim como acima
   */
  var category2 = [];

  $.each( nodes.find( 'li[data-term="' + c2 + '"] ul li' ), function() {
    category2.push( $( this ).attr( 'data-term' ) );
  });
  
  terms = $( terms ).filter( category2 );
  
  /**
   * Separado porque a linha acima estaria dentro de um IF
   */
  terms = jQuery.unique( terms );
  
  // Fazendo a interseção

  nodes = nodes.find( 'li' ).filter( function() {
    return ( $.inArray( $( this ).attr( 'data-term' ), terms ) != -1 );
  });
  
  console.log( terms );
  console.log( nodes )
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script><ulid="taxonomy">

  <li data-term="category 1">
    Categoria 1

    <ul>


      <li data-term="subcategory 1">

        Subcategoria 1

        <ul>

          <li data-term="Item #1">
            <a href="#">Item #1</a>
          </li>

          <li data-term="Item #2">
            <a href="#">Item #2</a>
          </li>

        </ul>

      </li>

      <li data-term="subcategory 2">

        Subcategoria 2


        <ul>

          <li data-term="Item #3">
            <a href="#">Item #3</a>
          </li>

          <li data-term="Item #4">
            <a href="#">Item #4</a>
          </li>

          <li data-term="Item #5">
            <a href="#">Item #5</a>
          </li>

        </ul>

      </li>

    </ul>
  </li>


  <li data-term="category 2">
    Categoria 2

    <ul>


      <li data-term="subcategory 3">

        Subcategoria 3


        <ul>

          <li data-term="Item #4">
            <a href="#">Item #4</a>
          </li>
          
          <li data-term="Item #6">
            <a href="#">Item #6</a>
          </li>

          <li data-term="Item #7">
            <a href="#">Item #7</a>
          </li>

        </ul>

      </li>

    </ul>
  </li>

</ul>
  

For some reason the code generates (a lot of) script error (s) in the inline editor , so I'll leave a Fiddle .

I've modified a lot from the previous revision, much to my liking, and now compare it to jQuery.inArray () , textually.

By opening the browser console you can see that I first filter by the first category and then by the second and this only returns the Item # 4 .

It works, not ideal, but it works.

However, because it is a Taxonomy, eventually the terms will be repeated. I was able to reproduce a single repetition in that snippet.

Even though the terms array is clean, with no reps, the nodes collection holds both <li> of Item # 4 because both have valid data-attributes in the filtering scope.

And I can not remove this duplicate node, nor with this approach I found.

Any ideas?

    
asked by anonymous 31.12.2017 / 16:06

0 answers