创建树结构的JSON
我有一个对象列表,类型为TDepartment,如下所示创建树结构的JSON,json,delphi,recursion,Json,Delphi,Recursion,我有一个对象列表,类型为TDepartment,如下所示 TDepartment = class ID : Integer; Name : string; ParentDepartmentID : Integer; end; 我需要创建一个TJSONObject,其中包含一个部门数组,也可以包含一个部门数组。因此,这个问题的深度不得而知 我现在的处境对我来说毫无意义,但我希望生成的JSON如下所示: "department_id": "5", "department
TDepartment = class
ID : Integer;
Name : string;
ParentDepartmentID : Integer;
end;
我需要创建一个TJSONObject,其中包含一个部门数组,也可以包含一个部门数组。因此,这个问题的深度不得而知
我现在的处境对我来说毫无意义,但我希望生成的JSON如下所示:
"department_id": "5",
"department_name": "100",
"parent_dept_id": "",
"subdepartments": [{
"department_id": "8",
"department_name": "300",
"parent_dept_id": "5",
"subdepartments": [{
"department_id": "1",
"department_name": "310",
"parent_dept_id": "8",
"subdepartments": []
unit Unit1;
interface
uses
System.Generics.Collections;
type
TDepartment = class
ID : Integer;
Name : string;
ParentDepartmentID : Integer;
end;
TDepartmentStructure = class
ID : Integer;
Name : string;
ParentDepartmentID : Integer;
SubDepartments: TList< TDepartmentStructure >;
constructor Create( const pBasedOn : TDepartment );
end;
var
Department : TObjectList<TDepartment>;
function CopyStructure( pDepartment : TList<TDepartment> ) : TDepartmentStructure; // returns root
implementation
var
DepartmentStructure : TObjectList<TDepartmentStructure>;
function CopyStructure( pDepartment : TList<TDepartment> ) : TDepartmentStructure;
var
i, j: Integer;
begin
// stage one - copy everything
for i := 0 to pDepartment.Count - 1 do
begin
DepartmentStructure.Add( TDepartmentStructure.Create( pDepartment[ i ] ));
end;
// now go through and build structure
Result := nil;
for i := 0 to DepartmentStructure.Count - 1 do
begin
if DepartmentStructure[ i ].ID = 0 then
begin
// root
Result := DepartmentStructure[ i ];
end
else
begin
for j := 0 to DepartmentStructure.Count - 1 do
begin
if DepartmentStructure[ i ].ParentDepartmentID = DepartmentStructure[ j ].ID then
begin
DepartmentStructure[ j ].SubDepartments.Add( DepartmentStructure[ i ] );
break;
end;
end;
end;
end;
end;
{ TDepartmentStructure }
constructor TDepartmentStructure.Create(const pBasedOn: TDepartment);
begin
inherited Create;
ID := pBasedOn.ID;
Name := pBasedOn.Name;
ParentDepartmentID := pBasedOn.ParentDepartmentID;
SubDepartments:= TObjectList< TDepartmentStructure >.Create( FALSE ); // we do NOT own these objects!
end;
initialization
DepartmentStructure := TObjectList<TDepartmentStructure>.Create( TRUE );
finalization
DepartmentStructure.Free;
end.
请记住,每个级别都有未知数量的兄弟姐妹和孩子。
我想我需要编写一个递归过程,但我无法将其可视化。首先,您可能希望
TDepartment
的声明与您描述的嵌套结构相匹配:
TDepartment = class
ID : Integer;
Name : string;
ParentDepartmentID : Integer;
SubDepartments: array of TDepartment;
end;
为了将其序列化,我建议使用SuperObject库而不是内置的JSON类:
function TDepartment.Serialize: ISuperObject;
var Context: TSuperRttiContext;
begin
Context := TSuperRttiContext.Create;
try
Result := Context.AsJson<TDepartment>(self);
finally
Context.Free;
end;
end;
我将创建一个平行的树结构,保持原始结构不变。您当前的结构与您需要的相反,因此您可以扫描当前对象并将它们放置在树中。但在不了解当前结构的情况下,很难给出示例代码,但假设所有部门都存在于某种列表中,(我们称之为“部门”),并且“根”部门的父部门ID为零,则会出现如下情况:
"department_id": "5",
"department_name": "100",
"parent_dept_id": "",
"subdepartments": [{
"department_id": "8",
"department_name": "300",
"parent_dept_id": "5",
"subdepartments": [{
"department_id": "1",
"department_name": "310",
"parent_dept_id": "8",
"subdepartments": []
unit Unit1;
interface
uses
System.Generics.Collections;
type
TDepartment = class
ID : Integer;
Name : string;
ParentDepartmentID : Integer;
end;
TDepartmentStructure = class
ID : Integer;
Name : string;
ParentDepartmentID : Integer;
SubDepartments: TList< TDepartmentStructure >;
constructor Create( const pBasedOn : TDepartment );
end;
var
Department : TObjectList<TDepartment>;
function CopyStructure( pDepartment : TList<TDepartment> ) : TDepartmentStructure; // returns root
implementation
var
DepartmentStructure : TObjectList<TDepartmentStructure>;
function CopyStructure( pDepartment : TList<TDepartment> ) : TDepartmentStructure;
var
i, j: Integer;
begin
// stage one - copy everything
for i := 0 to pDepartment.Count - 1 do
begin
DepartmentStructure.Add( TDepartmentStructure.Create( pDepartment[ i ] ));
end;
// now go through and build structure
Result := nil;
for i := 0 to DepartmentStructure.Count - 1 do
begin
if DepartmentStructure[ i ].ID = 0 then
begin
// root
Result := DepartmentStructure[ i ];
end
else
begin
for j := 0 to DepartmentStructure.Count - 1 do
begin
if DepartmentStructure[ i ].ParentDepartmentID = DepartmentStructure[ j ].ID then
begin
DepartmentStructure[ j ].SubDepartments.Add( DepartmentStructure[ i ] );
break;
end;
end;
end;
end;
end;
{ TDepartmentStructure }
constructor TDepartmentStructure.Create(const pBasedOn: TDepartment);
begin
inherited Create;
ID := pBasedOn.ID;
Name := pBasedOn.Name;
ParentDepartmentID := pBasedOn.ParentDepartmentID;
SubDepartments:= TObjectList< TDepartmentStructure >.Create( FALSE ); // we do NOT own these objects!
end;
initialization
DepartmentStructure := TObjectList<TDepartmentStructure>.Create( TRUE );
finalization
DepartmentStructure.Free;
end.
单元1;
接口
使用
系统、泛型、集合;
类型
t部门=班级
ID:整数;
名称:字符串;
ParentDepartmentID:整数;
结束;
TDepartmentStructure=class
ID:整数;
名称:字符串;
ParentDepartmentID:整数;
子部门:TList;
构造函数创建(constpbasedon:TDepartment);
结束;
变量
部门:TObjectList;
函数CopyStructure(pDepartment:TList):TDepartmentStructure;//返回根
实施
变量
部门结构:TObjectList;
功能CopyStructure(pDepartment:TList):TDepartmentStructure;
变量
i、 j:整数;
开始
//第一阶段-复制所有内容
对于i:=0到pDepartment.Count-1 do
开始
DepartmentStructure.Add(TDepartmentStructure.Create(pDepartment[i]);
结束;
//现在完成并构建结构
结果:=无;
对于i:=0到DepartmentStructure.Count-1 do
开始
如果DepartmentStructure[i].ID=0,则
开始
//根
结果:=部门结构[i];
结束
其他的
开始
对于j:=0到DepartmentStructure.Count-1 do
开始
如果DepartmentStructure[i].ParentDepartmentID=DepartmentStructure[j].ID,则
开始
DepartmentStructure[j].SubDepartments.Add(DepartmentStructure[i]);
打破
结束;
结束;
结束;
结束;
结束;
{TDepartmentStructure}
构造函数TDepartmentStructure.Create(constpbasedon:TDepartment);
开始
继承创造;
ID:=pBasedOn.ID;
名称:=pBasedOn.Name;
ParentDepartmentID:=pBasedOn.ParentDepartmentID;
子部门:=TObjectList.Create(FALSE);//我们不拥有这些物品!
结束;
初始化
DepartmentStructure:=TObjectList.Create(TRUE);
定稿
部门结构。免费;
结束。
请注意,这仅用于说明目的。你可能不会创建和破坏我拥有的结构。一旦有了这个结构,您就可以使用当前的例程创建JSON记录了。我简化了代码,只是为了举个例子,实际上TDepartments有数百个属性和字段,它是旧框架中百万行以上代码库的一部分,因此JSON和TDepartment确实匹配。这也是我需要使用内置JSON类的原因,因为它们在整个应用程序中都会使用。您想将TDepartment的所有字段序列化为JSON,还是仅序列化示例中的字段?仅序列化示例中的字段:),但值得注意的是,父级与其子级之间的唯一关系是“父部门id”,而且部门本身没有“子部门”属性,这是一种非常糟糕的父子关系建模方法。。。我不相信您可以轻松地将类序列化到TJSONObject,但是如果您只需要几个字段,那么您可能希望以自己的方式实现。请看一下对我答案的编辑。@MattBaech SuperObject确实更易于使用,测试也更好。您可能可以创建它,然后将其导出为JSON字符串,然后从该字符串加载TJSONObject。您可以为TDepartment注册自定义序列化程序,然后使用SuperObject内置的typecast进行工作