我有一个 JSON 文件,我想根据 JSON 对象中的值组合创建多个 HTML 表。
让我们看一下 JSON 示例以提供更好的解释:
var data = {"headers":["plat","chan","cat","num"],"rows":[["plat1","chan1","cat1",1],
["plat1","chan1","cat1",2],["plat2","chan1","cat2",5]]};
在上面的示例中,我们有 2 行的前三列具有相同的值。我想生成一个包含一行的 HTML 表(因为值相同),但第四列必须有 SUM。
因此,HTML 表格必须类似于: plat1、chan1、cat1、3 plat2、chan1、cat2、5
下面的代码片段基于初始脚本和其他 stackoverflow 用户的帮助:)
var data = {"headers":["plat","chan","group","cat","num"],"rows":[["plat1","chan1","bbb","cat1",222],
["plat1","chan1","bbb","cat1",333],
["plat1","chan1","bbb","cat2",850]]};
// transform the data to get a clear connection between the
// heading and the corresponding data
const transformedData = data.rows.map((row) => {
const emptyRowDataObject = {};
return row.reduce((dataObjSoFar, rowData, rowDataIndex) => {
// for each of the values in the row, add a property
// with the name of the corresponding header
const correspondingHeader = data.headers[rowDataIndex];
dataObjSoFar[correspondingHeader] = rowData;
return dataObjSoFar;
}, emptyRowDataObject);
});
const headersOfInterest = ['plat','chan','cat','num'];
printTable(headersOfInterest, transformedData);
function printTable(headers, rowDataWithHeaders) {
let tableHeader = createTableHeaders(headers);
let tableRows = rowDataWithHeaders.map(row => createTableRow(headers, row));
let table = `<table>${ tableHeader }<tbody>${ tableRows }</tbody></table>`;
$("#one").html(table);
}
function createTableHeaders(headers) {
let headersHTML = '<thead><tr>';
headers.forEach(header => {
headersHTML += `<th>${ header }</th>`;
});
headersHTML += '</tr></thead>';
return headersHTML;
}
function createTableRow(headers, dataRow) {
let tr = '<tr>';
// go through all the headers we are interested in
// and get the corresponding value from this data row
headers.forEach(header => {
tr += `<td>${ dataRow[header] }</td>`;
});
tr += '</tr>';
return tr;
}
function getSumOfValuesInColumn(headerName, rowDataWithHeaders) {
// this could be done with Array.reduce as well
let sum = 0;
for(let i = 0; i < rowDataWithHeaders.length; i++) {
sum += rowDataWithHeaders[i][headerName]
}
return sum;
}
function printSummationTable(headersToSum, dataRows) {
const tableHeader = createTableHeaders(headersToSum);
const sumData = {};
headersToSum.forEach(header => {
sumData[header] = getSumOfValuesInColumn(header, dataRows);
});
// treat sumData as a single table row
const tableRows = createTableRow(headersToSum, sumData);
let table = `<table>${ tableHeader }<tbody>${ tableRows }</tbody></table>`;
$("#two").html(table);
}
const headersToSum = ['plat','chan','cat','num'];
printSummationTable(headersToSum, transformedData);
@import url('https://fonts.googleapis.com/css?family=Roboto');
body {
margin: 0;
color:#fff;
font-family: Roboto; }
.row {
display: table;
width: 100%;
height: 241px;
background-color:#454545;
}
.row > .col-lg-6 {
display: table-cell;
vertical-align: middle;
}
.container {
/*display: flex;*/
flex-wrap: wrap;
}
.container > div {
padding: 15px;
margin: 5px;
flex: 0 0 calc(100% - 20px);
text-align: left;
}
/*img {
padding-left: 7%;
max-height:55px;
width:auto;
}*/
td{
padding: 2px 2px;
text-align: center;
margin: 6px 0;
border: none;
}
table{
width: 100%;
background-color:#454545;
font-weight:500;
border-collapse: separate;
border-spacing:0.3em 1.1em;
color: #fff;
border: 0;
}
tr{
font-size: 1.5em;
text-transform:capitalize;
}
tr:nth-child(1) {
color: #CCC;
font-size: 1.5em;
}
#one,#two,#three,#four{
padding-top:2%;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<h4 style="color:#000;">Table before summing the number for the rows that have the same value in the first three columns</h4>
<div id="one"></div>
<h4 style="color:#000;">Table where we can see the SUM but for all the rows. The first three columns are a concatenation of the values which should not happen.</h4>
<div id="two"></div>
<h4 style="color:#000;">Table that I want to get (static)</h4>
<div><table> <thead> <tr> <th>plat</th> <th>chan</th> <th>cat</th> <th>num</th> </tr></thead> <tbody> <tr> <td>plat1</td><td>chan1</td><td>cat1</td><td>555</td></tr><tr> <td>plat1</td><td>chan1</td><td>cat2</td><td>850</td></tr></tbody></table></div>
最佳答案
我创建了以下答案,希望它能满足您的需求。
var data = {
"headers":["plat","chan","group","cat","num"],
"rows":[
["plat1","chan1","bbb","cat1",222],
["plat1","chan1","bbb","cat1",333],
["plat1","chan1","bbb","cat2",850]
]
};
function transformData(rows) {
const
rowMap = new Map(),
result = [];
// Iterate over the rows.
rows.forEach(row => {
const
// Create a key, it is the first 4 elements joined together.
key = row.slice(0,4).join();
// Check if the Map has the generated key...
if (rowMap.has(key)) {
// The map has the key, we need to add up the values
const
// Get the value for the current key.
storedRow = rowMap.get(key);
// Add the value of the current row to the row in the map.
storedRow[4] += row[4];
} else {
// The key doens't exist yet, add the row to the map.
rowMap.set(key, row);
}
});
// Iterate over all the entries in the map and push each value with the
// summed up value into the array.
rowMap.forEach(value => {
result.push(value);
});
// Return the array.
return result;
}
// Creates cells for all items in the row array. When no cell type is set
// the method will create td elements.
function getCells(row, element = 'td') {
// Reduce the array to a single string.
return row.reduce((result, cell) => {
result += `<${element}>${cell}</${element}>`;
return result;
}, '');
}
// Creates tr elements for each item in the rows array, each tr element
// will be filled with td elements.
function getBody(rows) {
// Reduce the array to a single string.
return rows.reduce((result, row) => {
result += `<tr>${getCells(row)}</tr>`
return result;
}, '');
}
// Create the HTML table.
function createTable(tableData) {
let
tableHTML = '';
tableHTML = `<table>
<thead><tr>${getCells(tableData.headers, 'th')}</tr></thead>
<tbody>${getBody(tableData.rows)}</tbody>
</table>`;
return tableHTML;
}
data.rows = transformData(data.rows);
const
generateHTML = createTable(data);
$("#two").html(generateHTML);
@import url('https://fonts.googleapis.com/css?family=Roboto');
body {
margin: 0;
color:#fff;
font-family: Roboto; }
.row {
display: table;
width: 100%;
height: 241px;
background-color:#454545;
}
.row > .col-lg-6 {
display: table-cell;
vertical-align: middle;
}
.container {
/*display: flex;*/
flex-wrap: wrap;
}
.container > div {
padding: 15px;
margin: 5px;
flex: 0 0 calc(100% - 20px);
text-align: left;
}
/*img {
padding-left: 7%;
max-height:55px;
width:auto;
}*/
td{
padding: 2px 2px;
text-align: center;
margin: 6px 0;
border: none;
}
table{
width: 100%;
background-color:#454545;
font-weight:500;
border-collapse: separate;
border-spacing:0.3em 1.1em;
color: #fff;
border: 0;
}
tr{
font-size: 1.5em;
text-transform:capitalize;
}
tr:nth-child(1) {
color: #CCC;
font-size: 1.5em;
}
#one,#two,#three,#four{
padding-top:2%;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<h4 style="color:#000;">Result table (dynamic).</h4>
<div id="two"></div>
<h4 style="color:#000;">Table that I want to get (static)</h4>
<div><table> <thead> <tr> <th>plat</th> <th>chan</th> <th>cat</th> <th>num</th> </tr></thead> <tbody> <tr> <td>plat1</td><td>chan1</td><td>cat1</td><td>555</td></tr><tr> <td>plat1</td><td>chan1</td><td>cat2</td><td>850</td></tr></tbody></table></div>
关于javascript - 根据前 3 列对 JSON 数据进行分组,并对 HTML/JS 中第 4 列的编号进行求和,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46026882/