问题描述
我有一个数据表,作为一个javascript数组保存,我需要多个小计。我知道我可以使用数组的reduce方法来提供总计,但是无法使小计与数据交错。 我能想到的获得交错输出的唯一方法是作为对象或json文字。
对于具有“名称”,“工作参考”,“位置”,“星期编号”,“日期”,“持续时间”的示例表,我希望获得“星期编号”,“名称”的持续时间总和, “位置”,“职位参考”。
输出类似于
{ “周号”:“ Wk 44”, “名称”:[ { “名称”:“ Elmer Fudd”, “位置”:[ { “位置”:“镇”, “求职信”:[ { “求职信”:“购买弹药”, “持续时间”:2 } ], “持续时间”:2 }, { “位置”:“树林”, “求职信”:[ { “工作参考资料”:“ Build Fire”, “持续时间”:7.5 }, { “求职者”:“赶上兔子”, “持续时间”:19.75 }, { “工作参考资料”:“切木”, “持续时间”:9 } ], “持续时间”:36.25 } ], “持续时间”:38.25 }, { “名称”:“优胜美地山姆”, “位置”:[ { “位置”:“矿山”, “求职信”:[ { “工作参考”:“前景”, “持续时间”:17.00 } ], “持续时间”:17.00 }, { “位置”:“镇”, “求职信”:[ { “求职信”:“购买弹药”, “持续时间”:2.0 }, { “求职信”:“ Rob Stagecoach”, “持续时间”:12.50 } ], “持续时间”:14.5 }, { “位置”:“树林”, “求职信”:[ { “求职信”:“抓兔子”, “持续时间”:17.0 } ], “持续时间”:17.0 } ], “持续时间”:48.5 } ], “持续时间”:86.75 }
我最新的代码:
- 所有行的总计作为数据表
- 通过多个属性进行分组(但不完美,因为groupby是级别值的组合)
我正在努力使小计与分组数据交织在一起。
'use strict';
// input data is in the form of a 2d array with column headers in [0]
let times = [
["Name","Job Ref","Location","Week No","Date","Duration"],["Elmer Fudd","Catch Wabbit","Woods","Wk 44","2020-10-26T00:00:00.000Z",1],"Buy Ammo","Town",2],5],"Build Fire","2020-10-27T00:00:00.000Z",7.5],"Cut Wood","2020-10-28T00:00:00.000Z",9],"2020-10-29T00:00:00.000Z",6.25],"2020-10-30T00:00:00.000Z",["Yosemite Sam",1.0],7.0],"Rob Stagecoach",12.50],"Prospect","mine",4.00],5.00],1.00],3],6]
];
// split to give headers and data by shifting
let h = times.shift();
// then reduce for total Duration
let a = times.reduce(function (a,x) { return (a + x[h.indexOf("Duration")]); },0);
console.log('Total Duration for input data %d',a);
// map the times to an array of timing objects
let t = times.map((row) => rowToObject(row,h));
//console.log(t);
a = groupBy(t,'Location');
//console.log(a);
a = groupBy(t,'Name');
//console.log(a);
// aggregate as an array of objects
a = groupByMultipleKeys(t,['Name','Location','Job Ref'])
console.log(a);
function rowToObject(arr,headers) {
if (arr.length != headers.length) { throw ('Row and Headers are not the same size'); };
return arr.reduce((rv,x,i) => { rv[headers[i]] = x; return rv; },{});
}
function groupBy(xs,key) {
let g = xs.reduce(function (rv,x) {
(rv[x[key]] = rv[x[key]] || []).push(x);
return rv;
},{});
return g;
}
function groupByMultipleKeys(data,keys) { // `data` is an array of objects,`keys` is the array of keys (or property accessor) to group by
// reduce runs this anonymous function on each element of `data` (the `item` parameter,// returning the `storage` parameter at the end
return data.reduce((storage,item) => {
// returns an object containing keys and values of each item
const groupValues = keys.reduce((values,key) => {
values[key] = item[key];
return values;
},{});
// get the first instance of the key by which we're grouping
const group = Object.values(groupValues).join(' ');
// set `storage` for this instance of group to the outer scope (if not empty) or initialize it
storage[group] = storage[group] || [];
// add this item to its group within `storage`
if (keys.every((key) => item[key] === groupValues[key])) {
storage[group].push(item);
}
// return the updated storage to the reduce function,which will then loop through the next
return storage;
},{}); // {} is the initial value of the storage
};
不好意思的格式!
解决方法
暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!
如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。
小编邮箱:dio#foxmail.com (将#修改为@)