问题描述
我的前端打字稿文件中有此列表:
I have this list in my front-end typescript file:
poMonths:
0: {id: 1, companyName: "company14", companyId: 14, flActive: true, purchaseMonth: "2019-12-15T00:00:00", purchaseMonthString: "Dec-2019" , year: 2019, month: "December"}
1: {id: 2, companyName: "company5", companyId: 5, flActive: true, purchaseMonth: "2019-12-15T00:00:00", …}
2: {id: 3, companyName: "company13", companyId: 13, flActive: true, purchaseMonth: "2019-11-15T00:00:00", …}
3: {id: 4, companyName: "company14", companyId: 14, flActive: true, purchaseMonth: "2019-11-15T00:00:00", …}
4: {id: 5, companyName: "company5", companyId: 5, flActive: true, purchaseMonth: "2019-10-15T00:00:00", …}
5: {id: 6, companyName: "company14", companyId: 14, flActive: true, purchaseMonth: "2020-09-15T00:00:00", …}
6: {id: 7, companyName: "company7", companyId: 7, flActive: true, purchaseMonth: "2020-09-15T00:00:00", …}
我想从中获取嵌套的类型化树,与此类似,但采用类型化格式:
I would like to get a nested typed tree out of it, something similar to this but in a typed format:
因此,我正在使用此功能将列表分组为所需的内容:
So I am using this function to group the list to what I want:
groupBy() {
const result = this.poMonths.reduce((state, current) => {
const { companyName, year, month } = current;
const company = state[companyName] || (state[companyName] = {});
const yearObj = company[year] || (company[year] = {});
const monthArr = yearObj[month] || (yearObj[month] = []);
monthArr.push(current);
return state;
}, {});
return result;
}
但是,未键入返回值,它只是一个JSON对象.例如,如何使用这些类型来键入它?:
However, the returned value is not typed, it is just a JSON object. How can I make it typed utilizing these types for instance?:
export class ItemNode {
children: ItemNode[];
item: string;
}
/** leaf item node with database id information. each leaf will be a single leaf containing an id from the database */
export class LeafItemNode {
id?: number;
companyId: number;
companyName: string;
flActive: boolean;
purchaseMonth: Date;
purchaseMonthString: string;
year: number;
month: number;
}
基本上,树应该一直由ItemNode组成,一直到叶子为止都是LeafItemNode(包含ID)
Basically, the tree should consist of ItemNodes all the way down to the leaves which would be LeafItemNode (containing the IDs)
推荐答案
您可以继续使用.reduce()
,但是现在您必须以数组作为初始对象:
You can keep using .reduce()
however now you have to start with an array as inital object:
let initialState: ItemNode[] = [];
const result: ItemNode[] = input.reduce((state, current) => {
const { companyName, year, month } = current;
let company = state.find(x => x.item == companyName);
if (!company) {
company = new ItemNode();
company.item = companyName;
company.children = [];
state.push(company);
}
let yearObj = company.children.find(x => x.item == year.toString());
if (!yearObj) {
yearObj = new ItemNode();
yearObj.item = year.toString();
yearObj.children = [];
company.children.push(yearObj);
}
let monthObj = yearObj.children.find(x => x.item == month.toString());
if (!monthObj) {
monthObj = new ItemNode();
monthObj.item = month.toString();
monthObj.children = [];
yearObj.children.push(monthObj);
}
let cur = new ItemNode();
cur.item = id.toString();
monthObj.children.push(cur);
return state;
}, initialState);
JS可测试版本:
class ItemNode {}
let input = [{id: 1, companyName: "company14", companyId: 14, flActive: true, purchaseMonth: "2019-12-15T00:00:00", year: 2019, month: "December"},
{id: 2, companyName: "company5", companyId: 5, flActive: true, purchaseMonth: "2019-12-15T00:00:00", year: 2019, month: "December"},
{id: 3, companyName: "company13", companyId: 13, flActive: true, purchaseMonth: "2019-11-15T00:00:00", year: 2019, month: "November"},
{id: 4, companyName: "company14", companyId: 14, flActive: true, purchaseMonth: "2019-11-15T00:00:00", year: 2019, month: "December"},
{id: 5, companyName: "company5", companyId: 5, flActive: true, purchaseMonth: "2019-10-15T00:00:00", year: 2019, month: "October"},
{id: 6, companyName: "company14", companyId: 14, flActive: true, purchaseMonth: "2020-09-15T00:00:00", year: 2020, month: "September"},
{ id: 7, companyName: "company7", companyId: 7, flActive: true, purchaseMonth: "2020-09-15T00:00:00", year: 2020, month: "September" }]
let initialState = [];
const result = input.reduce((state, current) => {
const { id, companyName, year, month } = current;
let company = state.find(x => x.item == companyName);
if (!company) {
company = new ItemNode();
company.item = companyName;
company.children = [];
state.push(company);
}
let yearObj = company.children.find(x => x.item == year.toString());
if (!yearObj) {
yearObj = new ItemNode();
yearObj.item = year.toString();
yearObj.children = [];
company.children.push(yearObj);
}
let monthObj = yearObj.children.find(x => x.item == month.toString());
if (!monthObj) {
monthObj = new ItemNode();
monthObj.item = month.toString();
monthObj.children = [];
yearObj.children.push(monthObj);
}
let cur = new ItemNode();
cur.item = id.toString();
monthObj.children.push(cur);
return state;
}, initialState);
console.log(result);
这篇关于JavaScript/TypeScript中的类型分组依据-将JSON嵌套到类型嵌套数组中的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!