我正在尝试根据CrossFilter中的两个不同维度创建加权平均值。有没有办法编写自定义reduce函数来执行此操作?我有:
function reduceAddAvg(attr) {
return function(p,v) {
++p.count
p.sum += v[attr];
if (p.count == 0) { //so we don't divide by zero
p.avg = 0;
}else {
p.avg = p.sum/p.count;
}
return p;
}
}
function reduceRemoveAvg(attr) {
return function(p,v) {
--p.count
p.sum -= v[attr];
if (p.count == 0) {
p.avg = 0;
}else {
p.avg = p.sum/p.count;
}
return p;
}
}
function reduceInitAvg() {
return {count:0, sum:0, avg:0};
}
和
var rent = ndx.dimension(function(d){
return d.rent
})
var units = ndx.dimension(function (d){
return d.units
})
var hood = ndx.dimension(function (d) {
return d.hood;
});
我的数据如下:
records = [{"hood":"SF","rent":"1000","units":"4"},
{"hood":"NYC","rent":"1200","units":"5"},
{"hood":"SF","rent":"1400","units":"8"},
]
我想退还租金,按单位(租金*单位)/单位加权,结果会是这样的:
{"key":"SF","value": (1000 * 4 + 1400 * 8) / (4+8)}
{"key":"NY,"value": 1200}
Crossfilter是否支持此功能?我如何编写自定义reduce函数来实现它?
答案 0 :(得分:1)
这就是你要找的......
records = [{"hood":"SF","rent":1000,"units":4},
{"hood":"NYC","rent":1200,"units":5},
{"hood":"SF","rent":1400,"units":8}];
var ndx = crossfilter(records);
var hoodDim = ndx.dimension(function (d) {
return d.hood;
});
var hoodGroup = hoodDim.group().reduce(
function reduceAdd(p, v) {
p.sumOfProds += (v.rent * v.units);
console.log("sumOfProds", p.sumOfProds);
p.unitsSum += v.units;
console.log("unitsSum", p.unitsSum);
p.finalVal = p.sumOfProds / p.unitsSum;
return p;
},
function reduceRemove(p, v) {
p.sumOfProds -= (v.rent * v.units);
p.unitsSum -= v.units;
p.finalVal = p.unitsSum ? p.sumOfProds / p.unitsSum : 0;
return p;
},
function reduceInitial() {
return { sumOfProds:0, unitsSum:0, finalVal:0 };
});
hoodGroup.top(Infinity).forEach(function(d){ console.log(d.key, d.value.finalVal); });
如果需要,这是JSFiddle。