所以我遇到了这个问题,我需要每列的平均值和每行如下:
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新手。有没有更好的方法来实现这种影响?
答案 0 :(得分:0)
您可以使用嵌套的for
循环。创建一个填充0
的数组,为for
循环中的每个索引设置值,设置行的平均值后的总和和平均垂直列。请注意,要包含最后一行单元格的平均值,请将len
调整为len = cols.length
,即在最后-1
循环中移除len = 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);
}
})();
&#13;
<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>
&#13;
答案 1 :(得分:0)
此代码适用于水平计算平均值。这是一个如何使用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>";
}
答案 2 :(得分:0)
您可以使用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>
答案 3 :(得分:0)
一种方法如下:
// 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
});
&#13;
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;
}
&#13;
<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>
&#13;
参考文献:
Array.from()
。Array.prototype.forEach()
。Array.prototype.reduce()
。expression ? ifTrue : ifFalse
)。document.createElement()
。document.querySelector()
。document.querySelectorAll()
。Element.classList
。HTMLElement.style
。HTMLTableElement
。HTMLTableElement.rows
。Math.pow()
。Math.round()
。Node.appendChild()
。Node.cloneNode()
。Node.textContent
。parentNode.children
。parseFloat()
。String.prototype.trim()
。答案 4 :(得分:0)
你可以这样做,迭代行并首先填充最后一列。
更新行的平均列后,迭代第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>