簡體   English   中英

JavaScript中HTML表格內容列和行的平均值

[英]Average of HTML table content column and row in JavaScript

所以我遇到了這個問題,我需要每列的平均值和每行如下:

7 9 8
5 7 9
6 6 8

至:

7 9 8 8
5 7 9 7
6 6 8 6.7
6 7.3 8.3

這是我到目前為止所做的:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<table id="myTable">
    <tr>
        <td>7</td>
        <td>9</td>
        <td>8</td>
    </tr>
    <tr>
        <td>5</td>
        <td>7</td>
        <td>9</td>
    </tr>
    <tr>
        <td>6</td>
        <td>6</td>
        <td>8</td>
    </tr>
</table>
<script src="script.js"></script>
</body>
</html>

scipt.js里面:

(function () {
var table=document.getElementById("myTable");
var sum=0;
var row=table.rows;
console.log(row[0].innerText.split("  "));
var tr = document.createElement('tr');

for(var i=0, row; row.length>i; i++) {
    sum = sum + parseInt(table.rows[i].cells[0].innerHTML);
}

tr.insertCell(0).textContent = sum / 3;

table.appendChild(tr);

})();

我是JavaScript的新手。 有沒有更好的方法來實現這種影響?

您可以使用嵌套for循環。 創建一個填充0的數組,為for循環中的每個索引設置值,按照設置行的平均值設置總和和平均垂直列。 請注意,在最后一排的細胞,包括平均數的平均值,調整lenlen = cols.length ,即去掉-1len = cols.length -1最后for循環。

 (function() { var table = document.getElementById("myTable"); var row = table.rows; // store columns sums var cols = Array.from({length: row.length + 1}, () => 0); for (var i = 0; row.length > i; i++) { var td = document.createElement('td'); var sum = 0; for (var j = n = 0; j < row[i].cells.length; sum += n, cols[j] += n, j++) { n = +(row[i].cells[j].innerHTML); } row[i].insertCell(j) .innerHTML = "<b>" + (sum / row.length).toFixed(1) + "</b>"; // set column values cols[cols.length - 1] += (sum / row.length -1); } // set column averages table.insertRow(); var lastrow = table.rows[table.rows.length - 1]; // set `len` to `len = cols.length` to include average of averages for (var i = 0, len = cols.length - 1; i < len; i++) { var td = document.createElement('td'); var html = "<b>" + (cols[i] / len).toFixed(1) + "</b>"; td.innerHTML = html; lastrow.appendChild(td); } })(); 
 <table id="myTable"> <tr> <td>7</td> <td>9</td> <td>8</td> </tr> <tr> <td>5</td> <td>7</td> <td>9</td> </tr> <tr> <td>6</td> <td>6</td> <td>8</td> </tr> </table> 

這應該讓你走上正軌

此代碼適用於水平計算平均值。 這是一個如何使用for循環遍歷HTML元素,將其內容作為字符串進行迭代並將其轉換為ints的示例。

var table=document.getElementById("myTable");
var rows=table.rows;

for(var i = 0; i < rows.length; i++){
 var cells = rows[i].cells;
 var sum = 0;

 for(var x = 0; x < cells.length; x++){
  var cell = cells[x];
  sum += parseInt(cell.innerHTML);
 }
 var average = sum/cells.length;
 rows[i].innerHTML += "<td>"+average+"</td>";
}

工作小提琴

您可以使用parseFloat((sum/3).toFixed(1))來舍入總和:

 var table = document.getElementById("myTable"); var rows = table.rows; var myTable2 = document.getElementById("myTable2"); var newRows = ''; for (let i = 0; i < rows.length ; i++ ){ let numbers = rows[i].cells; //console.log(numbers[0]innerHTML); newRows += "<tr>"; let sum = 0; for (let j = 0 ; j < numbers.length ; j++){ sum += parseInt(numbers[j].innerHTML); newRows += "<td>" + numbers[j].innerHTML + "</td>"; }; newRows += "<td><b>" + parseFloat((sum/3).toFixed(1)) + "</b></td></tr>"; }; //console.log(newRows); myTable2.innerHTML = newRows; 
 <table border="1" id="myTable"> <tr> <td>7</td> <td>9</td> <td>8</td> </tr> <tr> <td>5</td> <td>7</td> <td>9</td> </tr> <tr> <td>6</td> <td>6</td> <td>8</td> </tr> <table> <table border="1" id="myTable2"> </table> 

一種方法如下:

// assigning the result of the immediately-invoked function expression
// (IIFE), the format of - among others - (function(){})()
// the final parentheses allow us to pass an argument to the enclosed
// function, to the 'averageTables' variable for subsequent use if
// required:
let averageTables = (function(opts) {

  /* the 'opts' Object passed as the argument is as follows:
    {
      // String: the CSS selector to identify the relevant
      // <table> elements:
      'table': '#myTable, #myOtherStrangelyIdenticalTable',

      // Boolean: whether or not you want to see the last cell
      // in the <table> the average of the averages column
      'hideAverageOfAverages': false,

      // String: the class-name to add to the <td> containing
      // the average of each <tr>:
      'rowAverageClassName': 'rowAverage',

      // String: the class-name to add to the <td> containing
      // the average of each column:
      'columnAverageClassName': 'columnAverage',

      // String: the class-name to add to the <td> containing
      // the average of the column of averages:
      'averageOfAveragesClassName': 'averageOfAverage',

      // Number: the number of decimal places to which the
      // averages should be rounded:
      'decimalPlaces': 1
    }
  */

  // here we use document.querySelectorAll() to retrieve the relevant
  // <table> elements, assuming that the opts.table selector results
  // in a selection of <table> elements:
  let tableElements = document.querySelectorAll(opts.table),

  // we use Array.from() to convert the NodeList from
  // document.querySelectorAll() into an Array:
    allTables = Array.from(tableElements),

  // here we create a new <td> element:
    newCell = document.createElement('td'),

  // here we find the divisor, and multiplier, for
  // accurately (insofar as JavaScript can) round
  // to a set number of decimal places:
    nDecimals = Math.pow(10, opts.decimalPlaces),

  // and initialise some empty variables for later
  // use:
    rows, column, cell, average;

  // here we use the Element.classList interface to add
  // the class-name passed in from the opts Object:
  newCell.classList.add(opts.rowAverageClassName);

  // we iterate over the Array of <table> elements using
  // Array.prototype.forEach():
  allTables.forEach(function(table) {

    // 'table' is a reference to the current <table> of the
    // Array of <table> elements over which we're iterating.

    // we cache the <tr> elements, as an Array, recovered
    // from the HTMLTableElement.rows collection:
    rows = Array.from(table.rows);

    // iterating over that Array of <tr> elements:
    rows.forEach(function(row) {
      // 'row' is a reference to the current <tr> element
      // from the Array of <tr> elements over which we're
      // iterating.

      // here we use Array.from() to create an Array of the
      // <td> elements that are the element-children of the
      // current <tr> element:
      average = Array.from(row.children)

        // we then use Array.prototype.reduce() to reduce
        // that Array to a single element:
        .reduce(function(value, currentCell) {
          // 'value': the current value of the reduce method,
          // (initialised to 0 as the final argument following
          // the anonymous function),
          // currentCell: the current <td> element of the
          // Array of <td> elements over which we're iterating.

          // here we add the currently-held value to the result
          // of retrieving the text-content of the current <td>,
          // and using String.prototype.trim() to remove any
          // leading or trailing white-space, and then passing
          // that resultant String to parseFloat() to convert
          // a numeric String to a number (if possible); note
          // that there are no sanity checks, so if the text
          // cannot be converted to a Number then the result of
          // reduce() will be either undefined or NaN.
          // This approach, obviously finds the sum of the text
          // of all <td> elements:
          return value + parseFloat(currentCell.textContent.trim());

      // following the summation, then, we divide it by the number
      // of <td> elements within the <tr> to find the average:
      }, 0) / row.children.length;

      // we clone the created <td> element:
      cell = newCell.cloneNode();

      // and set its text-content to the result of the following,
      // in which we multiply the found average by the value of
      // nDecimals, and use Math.round() on the result, and then
      // divide by the result of nDecimals to find the result to
      // the user-defined number of decimal places (using
      // Number.toFixed(n) will simply cut off the number without
      // rounding, which is possibly not a big issue in your use-case):
      cell.textContent = Math.round(average * nDecimals ) / nDecimals ;

      // here we append the created, cloned <td> to the current <tr>:
      row.appendChild(cell);
    });

    // here we simply find the last <tr> element in the <table>,
    // and then clone that node, including its children, using
    // cloneNode(true); it's worth remembering that
    // document.querySelector() returns only a single node, if any,
    // which is the first element it finds that matches the supplied
    // CSS selector:
    let newRow = table.querySelector('tr:last-child').cloneNode(true);

    // here we use Array.from() to convert the NodeList of newRow.children
    // into an Array, and then use Array.prototype.forEach() to iterate
    // over that Array:
    Array.from(newRow.children).forEach(function(cell, index) {
      // 'cell': a reference to the current <td> element of the
      // Array of <td> elements over which we're iterating,
      // 'index': the index of the current <td> within the Array
      // over which we're iterating.

      // retrieving a collection of <td> elements using the CSS
      // td:nth-child(), and interpolating the result of 'index + 1'
      // as the argument to :nth-child(); we add 1 to the index
      // because JavaScript is zero-based, whereas CSS is one-based; and
      // then using Array.from() to convert that collection into
      // an Array:
      column = Array.from(table.querySelectorAll('td:nth-child(' + (index + 1) + ')'));

      // here we calculate the average exactly the same way as above,
      // but over the columns rather than the rows:
      average = column.reduce(function(value, currentCell) {
        return value + parseFloat(currentCell.textContent.trim());
      }, 0) / column.length;

      // we set the cell's text-content exactly the same way
      // as above (which in DRY terms is, admittedly, ridiculous):
      cell.textContent = Math.round(average * 10) / 10;

      // here we add the user-supplied class-name to the
      // column-average <td> elements:
      cell.classList.add(opts.columnAverageClassName);

    });

    // and we then append the newRow to the current <table>
    // element:
    table.appendChild(newRow);

    // here we find the :last-child of the newly-added row,
    // which is the <td> containing the average of the
    // averages column:
    let averageOfAverage = newRow.querySelector('td:last-child');

    // here we set the display of that <td>, if the user wants to
    // hide the cell (opts.hideAverageOfAverages is true) then
    // we set the display style to 'none'; otherwise (if
    // opts.hideAverageOfAverages is anything other than exactly true)
    // we set the display to that of 'table-cell':
    averageOfAverage.style.display = opts.hideAverageOfAverages === true ? 'none' : 'table-cell';

    // and then we add the requisite, user-defined, class-name:
    averageOfAverage.classList.add(opts.averageOfAveragesClassName);
  });

  // at this point we return the Array of <tables> found
  // to the calling context if the user wants to have
  // use to them for any other reason:
  return allTables;

})({
  'table': '#myTable, #myOtherStrangelyIdenticalTable',
  'hideAverageOfAverages': false,
  'rowAverageClassName': 'rowAverage',
  'columnAverageClassName': 'columnAverage',
  'averageOfAveragesClassName': 'averageOfAverage',
  'decimalPlaces': 1
});

 let averageTables = (function(opts) { let tableElements = document.querySelectorAll(opts.table), allTables = Array.from(tableElements), newCell = document.createElement('td'), nDecimals = Math.pow(10, opts.decimalPlaces), rows, column, cell, average; newCell.classList.add(opts.rowAverageClassName); allTables.forEach(function(table) { rows = Array.from(table.rows); rows.forEach(function(row) { average = Array.from(row.children).reduce(function(value, currentCell) { return value + parseFloat(currentCell.textContent.trim()); }, 0) / row.children.length; cell = newCell.cloneNode(); cell.textContent = Math.round(average * nDecimals) / nDecimals; row.appendChild(cell); }); let newRow = table.querySelector('tr:last-child').cloneNode(true); Array.from(newRow.children).forEach(function(cell, index, all) { column = Array.from(table.querySelectorAll('td:nth-child(' + (index + 1) + ')')); average = column.reduce(function(value, currentCell) { return value + parseFloat(currentCell.textContent.trim()); }, 0) / column.length; cell.textContent = Math.round(average * nDecimals) / nDecimals; cell.classList.add(opts.columnAverageClassName); }); table.appendChild(newRow); let averageOfAverage = newRow.querySelector('td:last-child'); averageOfAverage.style.display = opts.hideAverageOfAverages === true ? 'none' : 'table-cell'; averageOfAverage.classList.add(opts.averageOfAveragesClassName); }); return Array.from(document.querySelectorAll(opts.table)); })({ 'table': '#myTable, #myOtherStrangelyIdenticalTable', 'hideAverageOfAverages': false, 'rowAverageClassName': 'rowAverage', 'columnAverageClassName': 'columnAverage', 'averageOfAveragesClassName': 'averageOfAverage', 'decimalPlaces': 1 }); 
 table { margin: 0 auto 1em auto; } td { width: 1.5em; height: 1.5em; border: 1px solid #000; text-align: center; } td.rowAverage { color: red; } td.columnAverage { color: limegreen; } td.columnAverage.rowAverage.averageOfAverage { color: rebeccapurple; font-weight: bold; } 
 <table id="myTable"> <tr> <td>7</td> <td>9</td> <td>8</td> </tr> <tr> <td>5</td> <td>7</td> <td>9</td> </tr> <tr> <td>6</td> <td>6</td> <td>8</td> </tr> </table> <table id="myOtherStrangelyIdenticalTable"> <tr> <td>7</td> <td>9</td> <td>8</td> </tr> <tr> <td>5</td> <td>7</td> <td>9</td> </tr> <tr> <td>6</td> <td>6</td> <td>8</td> </tr> </table> 

JS小提琴演示

參考文獻:

您可以執行此操作,迭代行並首先填充最后一列。

更新行的平均列后,迭代第n列並更新平均值。

這是一個示例:

 document.onreadystatechange = () => { if (document.readyState === 'complete') { var rows = document.querySelector("#myTable").rows; [].forEach.call(rows, (row) => { let currentSum = 0; let cells = row.cells; [].forEach.call(cells, (currentVal) => { currentSum += parseInt(currentVal.innerText, 10); }); appendElement(row, (currentSum / cells.length).toFixed(1)); }); let columnCount = document.querySelectorAll("tr:nth-child(1)>td").length; let rowContent = document.createElement("tr"); let table = document.querySelector("#myTable"); for (let idx = 0; idx < columnCount; idx++) { let columns = document.querySelectorAll("tr>td:nth-child(" + (idx + 1) + ")"); let currentSum = 0; [].forEach.call(columns, (column) => { currentSum += parseInt(column.innerText, 10); }); appendElement(rowContent, (currentSum / rows.length).toFixed(1)) } table.appendChild(rowContent); } }; function appendElement(parent, sum) { let cellEle = document.createElement("td"); cellEle.innerText = sum; cellEle.classList.add("bold"); parent.appendChild(cellEle); } 
 .bold { font-weight: bold; } 
 <table id="myTable"> <tr> <td>7</td> <td>9</td> <td>8</td> </tr> <tr> <td>5</td> <td>7</td> <td>9</td> </tr> <tr> <td>6</td> <td>6</td> <td>8</td> </tr> </table> 

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM