Calling push()
inside an each()
loop can typically be simplified with map()
Typically when an array is created and then a loop iterates over another array to push into that first array then the .map()
method could be used instead. With this approach the array can be assigned once and push()
does not need to be called within the loop.
jQuery has its own .map()
method. An array can be created using it combined with the .get()
method.
function tableToEmail() {
var recipients = $('input.selector:checked').map(function(){
var email = $(this).closest('tr').find('.email');
return email.text();
}).get();
console.log(recipients.join(','));
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.7.1/jquery.min.js"></script>
<table>
<tr>
<td><input type="checkbox" class="selector"></td>
<td class="name">John Doe</td>
<td class="country">Australia</td>
<td class="email">[email protected]</td>
</tr>
<tr>
<td><input type="checkbox" class="selector"></td>
<td class="name">Jane Smith</td>
<td class="country">Canada</td>
<td class="email">[email protected]</td>
</tr>
</table>
<button onclick="tableToEmail()">Get Emails</button>
A simpler selector can be used
Instead of selecting the checbox inputs, then navigating up to its parent before finding the sibling element with class email
, one could also use the jQuery :has()
selector along with the Subsequent-sibling combinator ~
to find the elements with class email
that have a previous sibling <td>
element which has a checked checkbox - i.e. td:has(input.selector:checked) ~ .email
function tableToEmail() {
var recipients = $('td:has(input.selector:checked) ~ .email')
.get() // Retrieve the elements matched by the jQuery object.
.map(el => $(el).text())
console.log(recipients.join(','));
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.7.1/jquery.min.js"></script>
<table>
<tr>
<td><input type="checkbox" class="selector"></td>
<td class="name">John Doe</td>
<td class="country">Australia</td>
<td class="email">[email protected]</td>
</tr>
<tr>
<td><input type="checkbox" class="selector"></td>
<td class="name">Jane Smith</td>
<td class="country">Canada</td>
<td class="email">[email protected]</td>
</tr>
</table>
<button onclick="tableToEmail()">Get Emails</button>
Using vanilla JS without jQuery
As the main heading on https://youmightnotneedjquery.com/ states:
You might not need jQuery
There is a CSS selector :has()
which has only been supported by modern browsers since December 20231. One could use document.querySelectorAll()
to get all the elements, put them into an array using the spread syntax ...
and then call .map()
to put the innerText
of each element into an array.
function tableToEmail() {
const emails = document.querySelectorAll('td:has(input.selector:checked) ~ .email');
const recipients = [...emails].map(el => el.innerText)
console.log(recipients.join(','));
}
<table>
<tr>
<td><input type="checkbox" class="selector"></td>
<td class="name">John Doe</td>
<td class="country">Australia</td>
<td class="email">[email protected]</td>
</tr>
<tr>
<td><input type="checkbox" class="selector"></td>
<td class="name">Jane Smith</td>
<td class="country">Canada</td>
<td class="email">[email protected]</td>
</tr>
</table>
<button onclick="tableToEmail()">Get Emails</button>