Reputation: 177
I'm having a hard time understanding the behaviour of jQuery's .toArray()
in this scenario.
I have 2 <table>
, one for "Participants" and one for "Winners".
I want to extract some data from these tables using jQuery.
I use 2 .map()
functions to transform the contents of the table into arrays/objects, have a look at the code:
<h2>Participants</h2>
<table border="1">
<tbody>
<tr>
<td>01</td>
<td>Andrew</td>
</tr>
<tr>
<td>02</td>
<td>Julian</td>
</tr>
<tr>
<td>03</td>
<td>Matt</td>
</tr>
<tr>
<td>04</td>
<td>Sarah</td>
</tr>
</tbody>
</table>
<h2>Winners</h2>
<table border="1">
<tbody>
<tr>
<td>01</td>
<td>Andrew</td>
</tr>
<tr>
<td>04</td>
<td>Sarah</td>
</tr>
</tbody>
</table>
const result = $('table')
.map((i, table) => {
return $(table)
.find('tbody tr')
.map((j, row) => {
const $row = $(row);
return {
number: $row.find('td:nth-child(1)').text(),
name: $row.find('td:nth-child(2)').text(),
};
})
.toArray(); // [1]
})
.toArray();
console.log(result);
[1] Without the .toArray()
I get an array with 2 jQuery objects, one for each table. (Great!)
But when I add .toArray()
all of a sudden it returns a single array with all the objects inside, why?
Where's the separation the was there before?!
[
[
{number: "01", name: "Andrew"},
{number: "02", name: "Julian"},
{number: "03", name: "Matt"},
{number: "04", name: "Sarah"}
],
[
{number: "01", name: "Andrew"},
{number: "04", name: "Sarah"}
]
]
[
{number: "01", name: "Andrew"},
{number: "02", name: "Julian"},
{number: "03", name: "Matt"},
{number: "04", name: "Sarah"},
{number: "01", name: "Andrew"},
{number: "04", name: "Sarah"}
]
I made a jsfiddle so you can see for yourself: https://jsfiddle.net/93cLyq6h/22/
Upvotes: 2
Views: 284
Reputation: 48751
The results of the $.fn.map
call needs to be wrapped in square brackets [ ... ]
.
const result = $('table')
.map((i, table) => [
$(table)
.find('tbody tr')
.map((j, row) => [{
number: $(row).find('td:nth-child(1)').text(),
name: $(row).find('td:nth-child(2)').text(),
}]).toArray()
]).toArray();
// Format results...
console.log(JSON.stringify(result, null, 2)
.replace(/\{\n\s+"/g, '{ "')
.replace(/,\n\s+"/g, ', ')
.replace(/"\n\s+\}/g, '" }'));
.as-console-wrapper { top: 0; max-height: 100% !important; }
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<h2>Participants</h2>
<table border="1">
<tbody>
<tr>
<td>01</td>
<td>Andrew</td>
</tr>
<tr>
<td>02</td>
<td>Julian</td>
</tr>
<tr>
<td>03</td>
<td>Matt</td>
</tr>
<tr>
<td>04</td>
<td>Sarah</td>
</tr>
</tbody>
</table>
<h2>Winners</h2>
<table border="1">
<tbody>
<tr>
<td>01</td>
<td>Andrew</td>
</tr>
<tr>
<td>04</td>
<td>Sarah</td>
</tr>
</tbody>
</table>
Upvotes: 0
Reputation: 75
Your issue is actually not with .toArray()
but with jquery's .map()
. Here is another answer explaining this, but when the .map() parameter function returns an array, each element is inserted into the set rather than the array itself. So your outer .map()
flattens the two arrays into one.
If an array is returned, the elements inside the array are inserted into the set.
Is there a jQuery map utility that doesn't automically flatten? here is something that should help you get what you're looking for.
Upvotes: 1