我在服务内部有一个可观察的对象,当订阅该服务时,该对象将返回一个对象,该对象的用户工作时间记录在他从事的每个项目中。
this.calculationService.getSumsByProject().subscribe(sum =>
console.log(sum);
}
该日志显示类似{undefined: 0, MISSING!: 16, Project1: 5, Project2:1, Project3: 20,Project4: 15}
项目是Project类型数组的一部分,看起来像这样:
projects: Project[] = [
{name: 'MISSING',ids:[]},
{name: 'Project1', ids:['pid75.22','pid75.23']},
{name: 'Project2', ids:['pid75.22','pid75.23']},
{name: 'Project3', ids:['pid66.1','pid33.99']},
{name: 'Project4', ids:['pdi75.88','pid99.15']}]
我有一个数组,其用户ID如下:
currentUserIds=['pid75.22','pid100.03','pid75.88','Not Specified']
我想做什么:
我的目标是解析对象的键-值对并添加记录在用户ID下的小时数。未指定将获取与用户没有通用ID的项目的小时数。
例如:
pid75.22:6
pid100.03:0
pid75.88:15
Not specified:36
到目前为止,我所做的事情以及卡住的地方
loggedProjectNames: string[];
loggedProjectHours: string[];
projectByName(name: string): Project {
return _.find(this.projects, { name }) || this.projects[0];
}
ngOnInit() {
this.calculationService.getSumsByProject().subscribe(sum => {
//console.log(sum);
this.loggedProjectNames = _.keys(sum);
this.loggedProjectHours = _.values(sum);
//console.log(this.loggedProjectNames,": ",this.loggedProjectHours);
this.loggedProjectNames.forEach(name => {
const found = this.projectByName(name);
this.currentUserIds.forEach(id => {
console.log(_.find(found.ids, i => i === id));
})
})
});
如何从这里开始?现在我检索了与密钥相关的项目,因此我不确定如何对公用ID记录的小时数进行分组
答案 0 :(得分:0)
您可以使用lodash _.flow()
创建一个进行转换的函数(请参见代码中的注释)。
const { flow, flatMap, map, partialRight: pr, groupBy, head, mapValues, zipObject, constant, times, size, sumBy, last, over, pick, omit, values, sum, spread, merge, partial } = _
const hoursByProject = {undefined: 0, 'MISSING!': 16, Project1: 5, Project2:1, Project3: 20,Project4: 15}
const createDefaults = userIds => zipObject(userIds, times(size(userIds), constant(0)))
const projectsBId = userIds => flow(
pr(flatMap, ({ name, ids }) => map(ids, id => [id, hoursByProject[name]])), // convert from project-ids to id-> project
pr(groupBy, head), // group all instance of id
pr(mapValues, g => sumBy(g, last)), // sum the hours for each id
over([
pr(pick, userIds), // get the values for the list of ids
flow(pr(omit, userIds), values, sum, s => ({ 'Not Specified': s })) // some the values for the others
]),
spread(partial(merge, createDefaults(userIds))) // merge to a single object with defaults of 0 for missing ids
)
const projects = [{"name":"MISSING","ids":[]},{"name":"Project1","ids":["pid75.22","pid75.23"]},{"name":"Project2","ids":["pid75.22","pid75.23"]},{"name":"Project3","ids":["pid66.1","pid33.99"]},{"name":"Project4","ids":["pid75.88","pid99.15"]}]
const currentUserIds = ['pid75.22','pid100.03','pid75.88','Not Specified']
const result = projectsBId(currentUserIds)(projects)
console.log(result)
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.11/lodash.js"></script>
以及terser lodash / fp版本:
const { flow, flatMap, map, groupBy, head, mapValues, sumBy, last, over, defaults, pick, omit, values, sum, mergeAll, zipObject, times, size, constant } = _
const hoursByProject = {undefined: 0, 'MISSING!': 16, Project1: 5, Project2:1, Project3: 20,Project4: 15}
const createDefaults = userIds => zipObject(userIds, times(constant(0), size(userIds)))
const projectsBId = userIds => flow(
flatMap(({ name, ids }) => map(id => [id, hoursByProject[name]], ids)), // convert from project + ids to id + hours
groupBy(head), // group all instance of id
mapValues(sumBy(last)), // sum the hours for each id
defaults(createDefaults(userIds)), // add default 0 values for all user ids
over([
pick(userIds), // get the values for the list of ids
flow(omit(userIds), values, sum, s => ({ 'Not Specified': s })) // some the values for the others
]),
mergeAll // merge to a single object
)
const projects = [{"name":"MISSING","ids":[]},{"name":"Project1","ids":["pid75.22","pid75.23"]},{"name":"Project2","ids":["pid75.22","pid75.23"]},{"name":"Project3","ids":["pid66.1","pid33.99"]},{"name":"Project4","ids":["pid75.88","pid99.15"]}]
const currentUserIds = ['pid75.22','pid100.03','pid75.88','Not Specified']
const result = projectsBId(currentUserIds)(projects)
console.log(result)
<script src='https://cdn.jsdelivr.net/g/lodash@4(lodash.min.js+lodash.fp.min.js)'></script>