7

Extracting this table into an array

$(function() {
  var $table = $("#results"),
    $headerCells = $table.find("thead th"),
    $rowCells = $table.find("tbody tr td");

  var headers = [],
    rows = [],
    combined = [];

  $headerCells.each(function(k, v) {
    headers[headers.length] = $(this).text();
  });

  $rowCells.each(function(k, v) {
    rows[rows.length] = $(this).text();
  });


  console.log(headers);
  console.log(rows);
  console.log($headerCells.length);
  console.log($rowCells.length);

  for (var i = 0; i < $rowCells.length; i++) {
    for (var j = 0; j < $headerCells.length; j++) {
      combined.push([$($headerCells[j]).text(), $($rowCells[i]).text()]);
    }
  }

  console.log(combined);
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<table id="results">
  <thead>
    <tr>
      <th>User Name</th>
      <th>User Job</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>fred nerk</td>
      <td>Admin</td>
    </tr>
    <tr>
      <td>Site Admin</td>
      <td>Dude</td>
    </tr>
    <tr>
      <td>User</td>
      <td>slave</td>
    </tr>
    <tr>
      <td>Admin</td>
      <td>god</td>
    </tr>
    <tr>
      <td>Specialist</td>
      <td>thing</td>
    </tr>
  </tbody>
</table>

The number of headers is not known in advance

to help, headers gives me

["User Name", "User Job"]

rows gives me

["fred nerk", "Admin", "Site Admin", "Dude", "User", "slave", "Admin", "god", "Specialist", "thing"]

If I try and combine these arrays I get something like

["User Name", "fred nerk"] ["User Job", "fred nerk"] ["User Name", "Admin"] ["User Job", "Admin"] ["User Name", "Site Admin"] ["User Job", "Site Admin"] ["User Name", "Dude"] ["User Job", "Dude"] ["User Name", "User"] ["User Job", "User"] ["User Name", "slave"] ["User Job", "slave"] ["User Name", "Admin"] ["User Job", "Admin"] ["User Name", "god"] ["User Job", "god"] ["User Name", "Specialist"] ["User Job", "Specialist"] ["User Name", "thing"] ["User Job", "thing"]

As you can see this is not quite right and I need to do the array of arrays instead.. Something like

[{"User Name": "fred nerk","User Job", "Admin"}...]...

Can someone help? I'm not really a JS person, so this is an uphill challenge for me :)

3 Answers 3

1

Just created the json object when you loop on your rows.

Consider the following example:

let headers = ["name", "job"];
let rows = ["fred nerk", "Admin","Site Admin", "Dude"];
let res = [];

function chunkArrayInGroups(arr, size) {
    let res = [];
    for(var i = 0; i < arr.length; i += size) {
        res.push(arr.slice(i, i+size));
    }
    return res;
}

rows = chunkArrayInGroups(rows, headers.length);

for (var i = 0; i < rows.length; i++) {
        let obj = {}; //for each rows create a JSON object
        for (var j = 0; j < headers.length; j++)
                obj[headers[j]] = rows[i][j];
        res.push(obj); // add object to result array
}
Sign up to request clarification or add additional context in comments.

2 Comments

the rows are not like that they are ["fred nerk", "Admin","Site Admin", "Dude"]
Could you update it so that it uses the latter code rows but with the first code block combining? it worked for me, but the next person would find it clearer if it was all one piece of code :)
1

You can simply use Array.reduce with an Array.map to get the result in a very concise manner once you have chunked the main array to the pieces you want:

let headers = ["name", "job", "awesome"];
let rows = ["John Smith", "Boss", true, "fred nerk", "Admin", false, "Site Admin", "Dude", false];

const chunkBy = (a,by=2) => a.reduce((r,c,i) => (i%by==0 ? r.push([c]) : r[r.length-1] = [...r[r.length-1], c], r), [])

let f = chunkBy(rows,3).map(x => x.reduce((r,c,i) => (r[headers[i]] = c,r), {}))

console.log(f)

This would also work with unknown headers as long as the data matches the headers - 3 headers - 3 props in the arrays etc.

2 Comments

rows aren\t like that.. they are one array
Then simply chunk the data to fit the header items #. See updated answer. You can use that ES6 chunkBy implementation or if you use underscore or lodash both have chunk-ing functions.
0

this should do it

// GET table headers
let header = $('#results').find('thead tr').children();
// Table body rows
let tableRow = $('#results').find('tbody').children();

let arr = [];
$.each(tableRow, function(i, tr){
    let obj = {};
    $.each(header, function(x, th){
        obj[$(th).html()] = $($(tr).children()[x]).html();
    });
    arr.push(obj);
});
console.log(arr);

1 Comment

This gives me 0: {User Name: "fred nerk", User Job: "fred nerk"} 1: {User Name: "Admin", User Job: "Admin"} 2: {User Name: "Site Admin", User Job: "Site Admin"} 3: {User Name: "Dude", User Job: "Dude"} 4: {User Name: "User", User Job: "User"} 5: {User Name: "slave", User Job: "slave"} 6: {User Name: "Admin", User Job: "Admin"} 7: {User Name: "god", User Job: "god"} 8: {User Name: "Specialist", User Job: "Specialist"} 9: {User Name: "thing", User Job: "thing"}

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.