1
\$\begingroup\$

I am hiding rows for given ids using this code:

var idArray = ['A123','B456']; // getting from web services
for (var i=0;i<idArray.length;i++) {
   var id = idArray[i];
   $("#eTable tr[data-empid=" + id + "]").hide();
}

HTML (Just for example doesn't needs improvement)

<table id="eTable">
    <tr data-empid="A123" data-salary="120" data-status="drone">
        <td>Peter</td>
        <td>Vogel</td>
        <td>Principal</td>
    </tr>
    <tr data-empid="B456" data-salary="130" data-status="worker">
        <td>Jan</td>
        <td>Vogel</td>
        <td>General Manager</td>
    </tr>
    <tr data-empid="C789" data-salary="110" data-status="worker">
        <td>Jason</td>
        <td>van de Velde</td>
        <td>Company nurse</td>
    </tr>
</table>

How can we improve this code as it is selecting same table again and again to get row one by one instead of getting them once?

\$\endgroup\$
3
\$\begingroup\$

I would recommend caching your <table> selector before the loop and simplifying the loop.

var idArray = ['A123','B456']; // getting from web services
var len = idArray.length;  // get the length
var $tbl = $('#eTable');  //cache the table selector

while (len--) {
 $tbl.find("tr[data-empid=" + idArray[len] + "]").hide();
}

This way you aren't re-selecting the entire table from the DOM on each loop. Also, since it doesn't matter what order the rows are hidden, the while(len--) is typically the "fastest" way to do a loop. No extra lookup to find the value of i and no recalculating of idArray.length on each loop.

In vanilla JavaScript:

var idArray = ['A123','B456']; // getting from web services
var len = idArray.length;  // get the length
var tbl = document.getElementById('eTable');  //cache the table selector

while (len--) {
 tbl.querySelector("tr[data-empid=" + idArray[len] + "]").style.display='none';
}
\$\endgroup\$
  • \$\begingroup\$ @Thriggle Crap! I didn't see that. Thanks for the catch! Updated. \$\endgroup\$ – Gary Storey Apr 29 '15 at 16:24
3
\$\begingroup\$

The performance benefits vary depending on the browser's implementation of ECMAScript, but you can usually get a modest performance improvement by selecting the parent element first, then selecting only child elements of that parent element. This jsPerf test somewhat demonstrates the difference.

In native JavaScript, this is done by selecting the parent element with document.querySelector, document.getElementById, or document.getElementsByTagName. You can then call a similar selector method on that element instead of on document to limit your search to only child elements.

Native

var idArray = ['A123','B456']; 
var table = document.querySelector("#eTable");
for(var i = 0; i < idArray.length; i++){
    table.querySelector("tr[data-empid='"+idArray[i]+"']").style.display = "none";
}

In jQuery, you can achieve the same using jQuery(parentElement).find(selector) or $(parentElement).find(selector)

jQuery

var idArray = ['A123','B456']; 
var table = $("#eTable");
for(var i = 0; i < idArray.length; i++){
   $(table).find("tr[data-empid='"+idArray[i]+"']").hide();
}
\$\endgroup\$
1
\$\begingroup\$

There are already a couple good answers to this, but I thought I'd take a different tack and use selectors rather than loops. Since you have an array of ids, you can use the fact that querySelectorAll and find can take multiple, comma-separated selectors within a single string and build one using join. So now, no more loops (except the implicit one in map).

var idArray = ['A123','B456']; // getting from web services

// Create selector
var selectors = idArray.map(function (id) { return 'tr[data-empid="' + id + '"]'; });
var selector = selectors.join(', ');

// Use plain JavaScript
var els = document.querySelector('#eTable').querySelectorAll(selector);
Array.prototype.forEach.call(els, function (el) { el.style.display = 'none'; });

// Use jQuery
$('#eTable').find(selector).hide();
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<table id="eTable">
    <tr data-empid="A123" data-salary="120" data-status="drone">
        <td>Peter</td>
        <td>Vogel</td>
        <td>Principal</td>
    </tr>
    <tr data-empid="B456" data-salary="130" data-status="worker">
        <td>Jan</td>
        <td>Vogel</td>
        <td>General Manager</td>
    </tr>
    <tr data-empid="C789" data-salary="110" data-status="worker">
        <td>Jason</td>
        <td>van de Velde</td>
        <td>Company nurse</td>
    </tr>
</table>

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.