如何在交叉筛选器.js中对时间进行分组、求和和平均时间



我正在尝试找到名称所花费的平均时间。我可以知道找到所有名称的总时间以及平均时间的最佳方法。请在下面找到详细信息

let data = [{"name":"A","children":"8:17:33"},{"name":"B","children":"9:30:45"},{"name":"C","children":"12:45:56"},{"name":"D","children":"4:20:30"},{"name":"E","children":"7:12:38"},{"name":"F","children":"6:29:45"},{"name":"G","children":"11:34:45"},{"name":"H","children":"10:30:45"},{"name":"I","children":"8:34:45"},{"name":"J","children":"8:34:12"}];
let CFX =  crossfilter(data);
let dimName = CFX.dimension( (d)=> d.name);
let grpTime = dimName.group().reduceSum( (d)=> d.children);
console.log( grpTime.all() );
<script src="https://square.github.io/crossfilter/crossfilter.v1.min.js"></script>

编辑:这是一个自定义的reduce来做到这一点,但结果时间显示为字符串,并且平均值太大:

let data = [{"name":"A","children":"8:17:33"},{"name":"B","children":"9:30:45"},{"name":"C","children":"12:45:56"},{"name":"D","children":"4:20:30"},{"name":"E","children":"7:12:38"},{"name":"F","children":"6:29:45"},{"name":"G","children":"11:34:45"},{"name":"H","children":"10:30:45"},{"name":"I","children":"8:34:45"},{"name":"J","children":"8:34:12"}];
	let CFX =  crossfilter(data);
	let dimName = CFX.dimension( (d)=> d.name);
	let grpTime = dimName.group().reduceSum( (d)=> d.children);
	//console.log( grpTime.all() );
	let timeGrp = dimName.group().reduce(
		function( p , v) {
			p.count++;
			let time = v.children.split(':');
			p.time += time[0] * 60 * 60 + time[1] * 60 + time[2];
			p.avg = p.time / p.count;
			return p;
		},
		function( p , v) {
			p.count--;
			let time = v.children.split(':');
			p.time -= time[0] * 60 * 60 + time[1] * 60 + time[2];
			p.avg = p.count ? p.time / p.count : 0;
			return p;
		},
		function( ) {
			return {
				time: 0,
				avg: 0,
				count : 0
			}
		}
	);
	console.log(timeGrp.all());
<script src="https://square.github.io/crossfilter/crossfilter.v1.min.js"></script>

JavaScript 的一个棘手问题是,它会默默地、愉快地将字符串转换为数字,反之亦然,而且它并不总是正确地做到这一点。

在这种情况下,由于您的时间是字符串,并且拆分这些字符串会产生更多字符串,因此您混合了字符串和数字。

但是JavaScript会抱怨吗?不。它会自动将字符串转换为数字,例如

"8" * 60 = 480

但它也会将数字转换为字符串,例如

90 + "9" = 909

正确的做法是立即将这些时间转换为数字:

let time = v.children.split(':').map(x => +x);

let data = [{"name":"A","children":"8:17:33"},{"name":"B","children":"9:30:45"},{"name":"C","children":"12:45:56"},{"name":"D","children":"4:20:30"},{"name":"E","children":"7:12:38"},{"name":"F","children":"6:29:45"},{"name":"G","children":"11:34:45"},{"name":"H","children":"10:30:45"},{"name":"I","children":"8:34:45"},{"name":"J","children":"8:34:12"}];
	let CFX =  crossfilter(data);
	let dimName = CFX.dimension( (d)=> d.name);
	let grpTime = dimName.group().reduceSum( (d)=> d.children);
	//console.log( grpTime.all() );
	let timeGrp = dimName.group().reduce(
		function( p , v) {
			p.count++;
			let time = v.children.split(':').map(x => +x);
			p.time += time[0] * 60 * 60 + time[1] * 60 + time[2];
			p.avg = p.time / p.count;
			return p;
		},
		function( p , v) {
			p.count--;
			let time = v.children.split(':').map(x => +x)
			p.time -= time[0] * 60 * 60 + time[1] * 60 + time[2];
			p.avg = p.count ? p.time / p.count : 0;
			return p;
		},
		function( ) {
			return {
				time: 0,
				avg: 0,
				count : 0
			}
		}
	);
	console.log(timeGrp.all());
<script src="https://square.github.io/crossfilter/crossfilter.v1.min.js"></script>

最新更新