Javascript 根据前3列对JSON数据进行分组,并计算HTML/JS中第4列的总数

Javascript 根据前3列对JSON数据进行分组,并计算HTML/JS中第4列的总数,javascript,jquery,html,json,Javascript,Jquery,Html,Json,我有一个JSON文件,我想根据JSON对象中的值组合创建多个HTML表 让我们看一个JSON示例,以给出更好的解释: var data = {"headers":["plat","chan","cat","num"],"rows":[["plat1","chan1","cat1",1], ["plat1","chan1","cat1",2],["plat2","chan1","cat2",5]]}; 在上面的示例中,前三列中有两行具有相同的值。我想生成一个只有一行的HTML表(因为值是相同的)

我有一个JSON文件,我想根据JSON对象中的值组合创建多个HTML表

让我们看一个JSON示例,以给出更好的解释:

var data = {"headers":["plat","chan","cat","num"],"rows":[["plat1","chan1","cat1",1],
["plat1","chan1","cat1",2],["plat2","chan1","cat2",5]]};
在上面的示例中,前三列中有两行具有相同的值。我想生成一个只有一行的HTML表(因为值是相同的),但第四列必须有总和

因此,HTML表必须如下所示: 平台1、通道1、cat1、3 平台2,通道1,cat2,5

下面的代码段基于初始脚本和stackoverflow用户的帮助:)

var data={“headers”:[“plat”、“chan”、“group”、“cat”、“num”],“rows”:[“plat1”、“chan1”、“bbb”、“cat1”,222],
[“平台1”、“通道1”、“bbb”、“cat1”,333],
[“plat1”、“chan1”、“bbb”、“cat2”、850]];
//转换数据以在
//标题和相应的数据
const transformedData=data.rows.map((row)=>{
常量emptyRowDataObject={};
返回row.reduce((dataObjSoFar、rowData、rowDataIndex)=>{
//对于行中的每个值,添加一个属性
//具有相应标头的名称
const correspondingHeader=data.headers[rowDataIndex];
dataObjSoFar[对应的标题]=行数据;
返回dataObjSoFar;
},emptyRowDataObject);
});
const headersof interest=['plat','chan','cat','num'];
打印表(感兴趣的标题、转换数据);
函数printTable(标题、rowDataWithHeaders){
let tableHeader=createTableHeaders(headers);
让tableRows=rowDataWithHeaders.map(row=>createTableRow(headers,row));
let table=`${tableHeader}${tableRows}`;
$(“#一”).html(表格);
}
函数createTableHeaders(headers){
让HeaderstML='';
headers.forEach(header=>{
headerstml+=`${header}`;
});
校长总人数+='';
返回总部;
}
函数createTableRow(标题、数据行){
让tr='';
//浏览所有我们感兴趣的标题
//并从该数据行中获取相应的值
headers.forEach(header=>{
tr+=`${dataRow[header]}`;
});
tr+='';
返回tr;
}
函数getSumOfValuesInColumn(headerName,rowDataWithHeaders){
//这也可以通过Array.reduce实现
设和=0;
for(设i=0;i{
sumData[header]=getSumOfValuesInColumn(header,dataRows);
});
//将sumData视为单个表行
const tableRows=createTableRow(headersToSum,sumData);
let table=`${tableHeader}${tableRows}`;
$(“#两”).html(表格);
}
const headersToSum=['plat','chan','cat','num'];
打印汇总表(headersToSum,转换数据);
@导入url('https://fonts.googleapis.com/css?family=Roboto');
正文{
保证金:0;
颜色:#fff;
字体系列:Roboto;}
.行{
显示:表格;
宽度:100%;
高度:241px;
背景色:#4545;
}
.row>.col-lg-6{
显示:表格单元格;
垂直对齐:中间对齐;
}
.集装箱{
/*显示器:flex*/
柔性包装:包装;
}
.container>div{
填充:15px;
保证金:5px;
弹性:0计算(100%-20px);
文本对齐:左对齐;
}
/*img{
左:7%;
最大高度:55px;
宽度:自动;
}*/
运输署{
填充:2px2px;
文本对齐:居中;
利润率:6px0;
边界:无;
}
桌子{
宽度:100%;
背景色:#4545;
字号:500;
边界塌陷:分离;
边界间距:0.3em 1.1em;
颜色:#fff;
边界:0;
}
tr{
字号:1.5em;
文本转换:大写;
}
tr:第n个孩子(1){
颜色:#CCC;
字号:1.5em;
}
#一、二、三、四{
垫面:2%;
}

表,然后对前三列中具有相同值的行数求和
表中,我们可以看到所有行的总和。前三列是不应该发生的值的串联。
我要获取的表(静态)

plat chan cat num plat1chan1cat1555 plat1chan1cat2850
我已经更新了html和javascript的代码。请试试这个。 让我知道,如果这对你有效,我会补充解释,如果需要的话

<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> </thead> 

<tbody> </tbody>

</table></div>

<script type="text/javascript">
var data = {"headers":["plat","chan","group","cat","num"],"rows":[["plat1","chan1","bbb","cat1",222],
["plat1","chan1","bbb","cat1",333],
["plat1","chan1","bbb","cat2",850]]};

createHeader();
createBody();
function createHeader(){
  $('thead').append((function(){
  var row = '<tr>';
 data.headers.forEach(function(element, index){
   row +='<th>' +element+'</th>'
}) 
 row += '</tr>'
 return row;
})())
}


function createBody(){
  var test = {};
data.rows.map(function(element, index){
var count = element.pop();
var content = element.join(':')
if(test[content]){
 test[content]= test[content]+count;
}else{
test[content] = count;
}
})
$('tbody').empty().append($.map(test, function(index, element){
  var row = '<tr>'
     element.split(':').map(function(ele, ind){
     row +='<td>'+ele+ '</td>'
   })
    row += '<td>'+index+ '</td></tr>'
    return row;
}))
}

</script>
将前三列中具有相同值的行数相加之前的
表
表中,我们可以看到所有行的总和。前三列是不应该发生的值的串联。
我要获取的表(静态)
var数据={“标题”:[“平台”、“通道”、“组”、“类别”、“数量”],“行”:[[“平台1”、“通道1”、“bbb”、“cat1”,222],
[“平台1”、“通道1”、“bbb”、“cat1”,333],
[“plat1”、“chan1”、“bbb”、“cat2”、850]];
createHeader();
createBody();
函数createHeader(){
$('thead').append((函数(){
var行=“”;
data.headers.forEach(函数(元素、索引){
行+=''+元素+''
}) 
行+=“”
返回行;
})())
}
函数createBody(){
var检验={};
data.rows.map(函数(元素、索引){
var count=element.pop();
var content=element.join(“:”)
如果(测试[内容]){
测试[内容]=测试[内容]+计数;
}否则{
测试[内容]=计数;
}
})
$('tbody').empty().append($.map)(测试、函数(索引、元素){
变量行=“”
element.split(“:”).map(函数(ele,ind){
行+=''+ele+''
})
行+=''+索引+''
返回行;
}))
}

我创建了以下答案,希望它能满足您的需要

var数据={
“标题”:[“平台”、“成龙”、“组”、“类别”、“数量”],
“行”:[
[“平台1”、“通道1”、“bbb”、“cat1”、222],
[“平台1”、“通道1”、“bbb”、“cat1”,333],
[“平台1”、“通道1”、“bbb”、“cat2”、850]
]
};
函数转换数据(行){
常数
行映射=新映射(),
结果=[];
//在行上迭代。
rows.forEach(row=>{
常数
//创建一个键,它是第一个
function printSummationTable(relevantHeaders, headerToSum, dataRows) {
  const tableHeader = createTableHeaders(relevantHeaders);
  const collapsedRows = 
    _(dataRows) // enhance the array, to enable chaining of (lodash) method calls
      .groupBy(comparisonStringForColumns(['plat', 'chan', 'cat'])) // results in an array (actually object.. but ignore that) of row groups (arrays)
      .map(peekWithMessage('After .groupBy'))
      .map(rowGroup => {
        // if we know we won't have to support more columns in the future
        // we can just copy the first of the groups (since the rows in the group are "duplicate")
        // BUT we add the "sum of the group" for the specific num value
        const collapsedRow = {...rowGroup[0]}; // check out "spread operator"
        collapsedRow.num = getSumOfValuesInColumn(headerToSum, rowGroup);
        return collapsedRow;
      })
      .map(peekWithMessage('After "collapse" step'))
      .value();
    // treat sumData as a single table row
  const tableRows = collapsedRows.map(row => createTableRow(relevantHeaders, row));
  let table = `<table>${ tableHeader }<tbody>${ tableRows }</tbody></table>`;
  $("#two").html(table);
}

// given a list of headerNames, give back a FUNCTION that
// takes a row an returns a concatinated string
// of the values corresponding to the headerNames
function comparisonStringForColumns(headerNames) {
    return function(row) {
    // make a string from the the relevant values
    // Used for grouping rows that should be considered the "same".
    let comparisonString = '';
    headerNames.forEach(header => {
      comparisonString += row[header];
    });
    return comparisonString;
  }
}


function peekWithMessage(message) {
    return function logAndPassThrough(x) {
    console.log(message, x);
    return x; // to be able to continue chaining
  }
}