23

私はこのHTMLテーブルを変換しようとしています:

ここに画像の説明を入力してください

コード:

<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>​​​​​​

jQueryを使用してjavascriptオブジェクトに:

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}]

ここに画像の説明を入力してください

具体的には...

  • idから取得されますtr
  • 、および値nameは各行から取得されますagegrade

私はこのjsfiddleをテスト用に作成しました:

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

ありがとう

4

6 に答える 6

31
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();

于 2012-09-05T23:13:05.753 に答える
10

列名をオーバーライドして非表示の行を無視できるようにするための機能がさらに必要だったことを除いて、これとまったく同じものが必要でした。https://github.com/lightswitch05/table-to-jsonにあるまさにそれを行うjQueryプラグインを作成しました

あなたの例では、次のようにします:(http://jsfiddle.net/ptVDm/118/

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

注意すべきことの1つは、IDは結果のオブジェクトの一部ではないということです。オブジェクトの配列の場所からIDを取得するだけで済みます。または、それをオブジェクトの一部にする必要がある場合は、IDの非表示の列を作成して、それらを含めることができます。

于 2013-02-13T18:28:10.047 に答える
8

以下が機能するはずです。

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までの設定に制限します。

Josiahのアプローチを見ると、私のものはプロパティ名を見つけることで賢くしようとしているので、おそらく私のものよりも速いでしょう。テーブルの構造が変わらないことが確実にわかっている場合は、彼のテクニックをお勧めします。そうでなければ、私のコードの行に何かが必要になります。

ああ、そして完全を期すために、これが私のJSFiddleです

于 2012-09-05T23:07:47.450 に答える
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();
于 2012-09-05T23:12:00.720 に答える
2

この場合、jQueryが大いに役立つのであれば、テーブル構造からかなり独立したプレーンなJSソリューションを次に示します。最初の行がヘッダー(別のテーブルセクション要素であるかどうかに関係なく)であり、行1+がデータである必要があります。

テーブルには必要な数の列または行を含めることができます。行スパンまたは列スパンが含まれていると、結果が混乱します(ただし、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;
}
于 2012-09-06T03:03:33.987 に答える
1

n列について以下のアプローチを試してください

デモ: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);
于 2012-09-05T23:20:41.027 に答える