使用 Javascript 过滤多个 HTML 表中的 JSON 数据

Posted

技术标签:

【中文标题】使用 Javascript 过滤多个 HTML 表中的 JSON 数据【英文标题】:Filtered JSON data in mulitple HTML tables with Javascript 【发布时间】:2018-02-11 20:05:45 【问题描述】:

我有一个 JSON 文件,我试图根据 JSON 中某些列的值返回多个 html 表。

目前我有以下工作。更具体地说,它将 JSON 值加载到表中,而不应用任何过滤器。

var data = "headers":["plat","chan","group","03","cat","05","06","07","08","09","10","11","12","13","14","15","16","17"],"rows":[["plat1","chan1","aaaa","xxxxx","cat1","yyyy",133,236,0,"656",0,956,37,36,12,67,1],
["plat1","chan1","aaaa","xxxxx","cat2","yyyy",178,867,0,"656",0,647,39,12,18,65,2],
["plat1","chan1","bbb","xxxxx","cat1","yyyy",378,867,0,"656",0,350,32,97,19,64,3],
["plat1","chan1","bbb","xxxxx","cat2","yyyy",137,167,0,"656",0,523,46,86,32,62,4],
["plat2","chan1","aaaa","xxxxx","cat1","yyyy",133,236,0,"656",0,956,37,36,12,67,1],
["plat2","chan1","aaaa","xxxxx","cat2","yyyy",178,867,0,"656",0,647,39,12,18,65,2],
["plat2","chan1","bbb","xxxxx","cat1","yyyy",378,867,0,"656",0,350,32,97,19,64,3],
["plat3","chan1","bbb","xxxxx","cat2","yyyy",137,167,0,"656",0,523,46,86,32,62,4]];
string = JSON.stringify(data);


//AAA Table + cat1

	var table1 = '<div class="row"><div class="col-lg-6" style="background-color: #e90649; width: 117px;">&nbsp;</div><div class="col-lg-6" style="max-width: 100px; padding-left: 10px; font-size: 2vw;">AAAA<br/><br/><span style="font-size: 1vw;">Cat1</span><br/><span style="font-size: 0.8vw; color: #ccc; font-weight: normal;">07 Jul 2017 - 18 Jul 2017</span></div><div class="col-lg-6"><div class="container"><table><thead><tr><th>plat</th><th>chan</th><th>03</th><th>05</th><th>06</th><th>07</th><th>08</th></tr></thead><tbody>';

	$.each(data.rows, function(i) 

		table1 +="<tr><td>" + data.rows[i][0] + "</td><td>" + data.rows[i][1] + "</td><td>" + data.rows[i][6] + "</td><td>" + data.rows[i][7] + "</td><td>" + data.rows[i][8] + "</td><td>" + data.rows[i][10] + "</td><td>" + data.rows[i][9] + "</td></tr>";
	);
	table1 += '</tbody></table></div></div></div>';
	$("#one").html(table1);
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>

<div id="one"></div>

结合三列的值,我有三个不同的类别。对于每个类别,JS 将返回一个 HTML 表格,但包含汇总的行。例如,对于 plat1 && chan1 && bbb 的组合,我们有 2 行,但在过滤后的表中,我希望看到 1 行的列数相加。作为开始,我正在尝试过滤 JSON 并创建一个表,但我被卡住了(我将使用与数字求和等相关的任何问题来更新问题)。

var data = "headers":["plat","chan","group","03","cat","05","06","07","08","09","10","11","12","13","14","15","16","17"],"rows":[["plat1","chan1","aaaa","xxxxx","cat1","yyyy",133,236,0,"656",0,956,37,36,12,67,1],
["plat1","chan1","aaaa","xxxxx","cat2","yyyy",178,867,0,"656",0,647,39,12,18,65,2],
["plat1","chan1","bbb","xxxxx","cat1","yyyy",378,867,0,"656",0,350,32,97,19,64,3],
["plat1","chan1","bbb","xxxxx","cat2","yyyy",137,167,0,"656",0,523,46,86,32,62,4],
["plat2","chan1","aaaa","xxxxx","cat1","yyyy",133,236,0,"656",0,956,37,36,12,67,1],
["plat2","chan1","aaaa","xxxxx","cat2","yyyy",178,867,0,"656",0,647,39,12,18,65,2],
["plat2","chan1","bbb","xxxxx","cat1","yyyy",378,867,0,"656",0,350,32,97,19,64,3],
["plat3","chan1","bbb","xxxxx","cat2","yyyy",137,167,0,"656",0,523,46,86,32,62,4]];
string = JSON.stringify(data);

var table1 = '';
$.each(data.rows, function(i) 
	//JSON to string for the Regex check
	if(JSON.stringify(data.rows[i][0]).match(/plat1/) && JSON.stringify(data.rows[i][4]).match(/cat1/) && JSON.stringify(data.rows[i][2]).match(/bbb/))
	
	    table1 += '<div class="row"><div class="col-lg-6" style="background-color: #e90649; width: 117px;">&nbsp;</div><div class="col-lg-6" style="max-width: 100px; padding-left: 10px; font-size: 2vw;">BBB<br/><br/><span style="font-size: 1vw;">Cat1</span><br/><span style="font-size: 0.8vw; color: #ccc; font-weight: normal;">07 Jul 2017 - 18 Jul 2017</span></div><div class="col-lg-6"><div class="container"><table><thead><tr><th>plat</th><th>chan</th><th>03</th><th>05</th><th>06</th><th>07</th><th>08</th></tr></thead><tbody>';
		
		$.each(data.rows, function(i) 
		
			table1 +="<tr><td>" + data.rows[i][0] + "</td><td>" + data.rows[i][1] + "</td><td>" + data.rows[i][6] + "</td><td>" + data.rows[i][7] + "</td><td>" + data.rows[i][8] + "</td><td>" + data.rows[i][10] + "</td><td>" + data.rows[i][9] + "</td></tr>";
		);
	
		table1 += '</tbody></table></div></div></div>';
	;
);

	$("#one").html(table1);
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>

<div id="one"></div>

我正在想办法做到这一点的最佳方式。我肯定需要一个循环来检查 a) 我有多少不同的组合,b) 在 HTML 中创建表,c) 创建显示 JSON 数据的子表。

【问题讨论】:

标题和行数组中的数据有什么关系?标头的顺序与数据点的顺序不同吗?例如,第三个标题03 应该对应于行数组中的第三个数据点? (像 aaa、bbb 等值).. 或者这对我来说是有意义的。但这不是您的第一个示例的工作方式。 对不起,我的意思是第三个标题 (group) 你从哪里得到这些值?这是从 Exel 导出的 CSV 还是什么?因为数据的结构使这个问题比其他情况更难解决。 @jonahe 我现在正在使用这个静态 JSON。 JSON 将在之后加载一个链接。 如果你能以 JSON 格式获取所有数据,那么操作原始数据几乎总是更容易,直到它看起来像你想要的那样,然后担心如何从中制作表格。这样,您就可以将查看逻辑(事物的呈现方式)与计算/统计/操作逻辑分开。我正在研究一个示例,我将很快在答案中发布。 【参考方案1】:

就像我在 cmets 中所说的,我认为更好的方法是将原始数据转换为更可用的格式,然后使用单独的逻辑来显示表格。这里我有一个例子,说明如何转换数据,让每一行都知道表头名称和数据之间的关联。

当数据采用正确的格式时,您将更容易看到您将如何对一列中的值求和(对与特定标题名称关联的值求和)。我也包含了一个例子。

您还可以看到我如何以较小的步骤(获取表格标题,获取 ONE 表格行)划分打印表格等大问题。然后我结合这些较小的函数来获得想要的行为。

对于数据转换,了解 Array 方法非常有用,例如 .map.forEach.reduce。我有他们每个人的例子。 Mozilla 对这些方法有很好的文档(见上文)。

我希望这可以帮助您了解如何继续解决问题,直到您拥有所需的所有功能。如果您还有其他问题,请随时问我!

编辑:这里的集成代码有点难以使用,所以我有一个 JSFiddle 演示,你可以在这里看到:https://jsfiddle.net/jonahe/jLnph69s/

编辑 2新的 JSFiddle 演示 现在有一个打印的 sum 示例:https://jsfiddle.net/jonahe/ntmg68dp/ 如您所见,它在很大程度上依赖于重用较小的函数从以前。

var data = "headers":["plat","chan","group","03","cat","05","06","07","08","09","10","11","12","13","14","15","16","17"],"rows":[["plat1","chan1","aaaa","xxxxx","cat1","yyyy",133,236,0,"656",0,956,37,36,12,67,1],
["plat1","chan1","aaaa","xxxxx","cat2","yyyy",178,867,0,"656",0,647,39,12,18,65,2],
["plat1","chan1","bbb","xxxxx","cat1","yyyy",378,867,0,"656",0,350,32,97,19,64,3],
["plat1","chan1","bbb","xxxxx","cat2","yyyy",137,167,0,"656",0,523,46,86,32,62,4],
["plat2","chan1","aaaa","xxxxx","cat1","yyyy",133,236,0,"656",0,956,37,36,12,67,1],
["plat2","chan1","aaaa","xxxxx","cat2","yyyy",178,867,0,"656",0,647,39,12,18,65,2],
["plat2","chan1","bbb","xxxxx","cat1","yyyy",378,867,0,"656",0,350,32,97,19,64,3],
["plat3","chan1","bbb","xxxxx","cat2","yyyy",137,167,0,"656",0,523,46,86,32,62,4]];

// 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',	'03',	'05',	'06',	'07',	'08'];
printTable(headersOfInterest, transformedData);
console.log('sum of column 06 is: ' , getSumOfValuesInColumn('06', transformedData));
console.log('transformed data looks like', 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;

  
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="one"></div>

【讨论】:

好的开始 :) 我得到了 8 行,就像我的例子一样。更改代码后如何对它们进行分组(对数字字段求和)?我遇到了一些错误:P 我用 JSFiddle 链接编辑了答案。在那里,您应该能够看到控制台中打印的总和。代码中的函数非常通用,因此如果您想要一个仅显示 plat 和 chan 的表格,则将参数 (headersOfInterest) 更改为函数。如果您想对不同字段的值求和,则相同。 我的问题有点笼统。发生了太多事情:P 我同意在将 JSON 加载到表中之前必须对其进行操作。我可以使用你的代码,我只需要找到一种巧妙的方法在某处添加一个 in 语句(例如,如果 plat1、chan1、group1 应该返回一行和最后一列的 SUM):jsfiddle.net/radomer/2yfw7y1n/1 是的,很难做到完全通用的解决方案。我不确定您可能需要哪些组合。但是我用一个新的 JSFiddle 演示再次编辑了答案。也向您的小提琴示例添加了相同的新代码。 jsfiddle.net/jonahe/2yfw7y1n/3 等我回来测试一下。我想用一行而不是两行查看第一个表(因为 Plat、Chan、Cat 在 2 行中具有相同的值)。 Num 应该显示 SUM。我会测试它并回来。可能是明天:P 我想我将不得不稍微修改一下代码。

以上是关于使用 Javascript 过滤多个 HTML 表中的 JSON 数据的主要内容,如果未能解决你的问题,请参考以下文章

[使用多个选择下拉列表过滤HTML表

如何使用JavaScript中的select将两个过滤器融合到一个表中?

即使我在 javascript 中应用过滤器,表数据也会保持刷新

多个表在 html 模板中使用循环,不带或带 javascript,与 e 相同的所有内容创建此表

如何使用HTML中的Javascript从对象获取多个输出?

使用 JavaScript 在客户端过滤项目、隐藏或从 DOM 中删除的最佳实践?