Подтвердить что ты не робот

Как преобразовать таблицу HTML в объект Javascript с помощью jQuery

Я пытаюсь преобразовать эту таблицу HTML:

enter image description here

Код:

<table id="students" border="1">
    <thead>
        <tr>
            <th>Name</th>
            <th>Age</th>
            <th>Grade</th>
        </tr>
    </thead>
    <tbody>
        <tr class="student">
            <td>Oscar</td>
            <td>23</td>
            <td>16.5</td>        
        </tr>
        <tr class="student">
            <td>Antonio</td>
            <td>32</td>
            <td>14</td>        
        </tr>
        <tr class="student">
            <td>Jessica</td>
            <td>21</td>
            <td>19</td>        
        </tr>
    </tbody>
</table>​​​​​​

В javascript-объект с использованием jQuery:

var tbl = $('table#students tr').map(function() {
  return $(this).find('td').map(function() {
    return $(this).text();
  }).get();
}).get();

Вышеприведенный код выведет следующий массив:

["Oscar", "23", "16.5", "Antonio", "32", "14", "Jessica", "21", "19"]

Все хорошо на этом этапе, но как я могу сделать, если я хочу, чтобы объекты javascript внутри массива имели следующую структуру:

[{id:1, name: "Oscar", age: 23, grade: 16.5}, {id:2, name: "Antonio", age: 32, grade: 14}, {id:3, name: "Jessica", age: 21, grade: 19}]

enter image description here

Просто чтобы быть более конкретным...

  • id получается из tr
  • Значения name, age и grade получаются из каждой строки

Я сделал это jsfiddle для проверки:

http://jsfiddle.net/oscarj24/ptVDm/

Спасибо

4b9b3361

Ответ 1

var tbl = $('#students tr:has(td)').map(function(i, v) {
    var $td =  $('td', this);
        return {
                 id: ++i,
                 name: $td.eq(0).text(),
                 age: $td.eq(1).text(),
                 grade: $td.eq(2).text()               
               }
}).get();

Ответ 2

Мне нужна эта точная вещь, за исключением того, что мне нужно было больше возможностей, чтобы переопределять имена столбцов и игнорировать любые скрытые строки. Я написал плагин jQuery, который делает именно это, расположенный здесь https://github.com/lightswitch05/table-to-json

для вашего примера вы бы сделали: (http://jsfiddle.net/ptVDm/118/)

var table = $('#students').tableToJSON();

Следует отметить, что идентификатор не является частью результирующего объекта. Вы можете просто получить идентификатор из местоположения массива объектов. Или, если вам действительно нужно, чтобы это было частью объекта, вы могли бы создать скрытый столбец для идентификатора, а затем они будут включены

Ответ 3

Следующее должно работать:

var cols = [];
var result = [];
$('#students>thead>th').each(function(){
    cols.push($(this).text().toLowerCase());
});
$('#students>tbody>tr').each(function(id){
    var row = {'id': id+1};
    $(this).find('td').each(function(index){
        row[cols[index]] = $(this).text();
    });
    result.push(row);
});

console.log(result);

В принципе, я нахожу свойства объекта из заголовка таблицы, затем я создаю объект для каждой строки, присваивая значения именам свойств, которые выводятся из более раннего массива.

Некоторые очевидные недостатки:

  • Если данные таблицы фактически по каким-либо причинам отличаются (например, пустые строки для косметики), эта система будет помещать пустые объекты в результирующий массив.
  • Если вы используете атрибут colspan в таблице, эта система не будет автоматически реплицировать одно и то же значение в разных объектных свойствах, а ограничится настройкой оставшихся <td> s.

Увидев подход Джосии, он, вероятно, быстрее, чем мой, поскольку мой пытается стать более умным, найдя имена собственности. Я бы рекомендовал его технику, если вы точно знаете, что ваша структура таблицы не изменится. В противном случае вам понадобится что-то в строках моего кода.

О, и для полноты, здесь JSFiddle с моим.

Ответ 4

Смотрите обновленный скрипт. Дополнительный массив map не нужен, потому что вы ищете данный объект для вашего JSON на данный момент.

var data = $('table#students tbody tr').map(function(index) {
    var cols = $(this).find('td');
    return {
        id: index + 1,
        name: cols[0].innerHTML,            // use innerHTML
        age: (cols[1].innerHTML + '') * 1,  // parse int
        grade: (cols[2].innerHTML + '') * 1 // parse int
    };
}).get();

Ответ 5

Попробуйте подходить для n столбцов

DEMO: http://jsfiddle.net/ptVDm/7/

var tblhdr = $('table#students th').map(function () {
    return $(this).text();
}).get();

console.log(tblhdr);

var tbl = $('table#students tbody tr').map(function(idx, el) {
    var td = $(el).find('td');
    var obj = {id: idx+1};

    //Can work on number of columns
    for (var i = 0; i < tblhdr.length; i++) {
        obj[tblhdr[i]] = td.eq(i).text();
    }

    return obj;
}).get();

console.log(tbl);

Ответ 6

Невозможно, если jQuery помогает в этом случае, здесь простое решение JS, которое не зависит от структуры таблицы. Это просто требует, чтобы первая строка была заголовком (может быть другим элементом таблицы таблицы или нет), а строки 1+ - это данные.

В таблице может быть столько столбцов или строк, сколько вам нравится, если там есть rowspan или colspans, это будет бесполезно с результатом (но jQuery тоже вам не поможет).

Он может быть легко адаптирован специально для использования заголовка для имен свойств и для игнорирования секции нижнего колонтитула:

function tableToObj(table) {
  var rows = table.rows;
  var propCells = rows[0].cells;
  var propNames = [];
  var results = [];
  var obj, row, cells;

  // Use the first row for the property names
  // Could use a header section but result is the same if
  // there is only one header row
  for (var i=0, iLen=propCells.length; i<iLen; i++) {
    propNames.push(propCells[i].textContent || propCells[i].innerText);
  }

  // Use the rows for data
  // Could use tbody rows here to exclude header & footer
  // but starting from 1 gives required result
  for (var j=1, jLen=rows.length; j<jLen; j++) {
    cells = rows[j].cells;
    obj = {};

    for (var k=0; k<iLen; k++) {
      obj[propNames[k]] = cells[k].textContent || cells[k].innerText;
    }
    results.push(obj)
  }
  return results;
}