我有一个TDepartment类型的对象列表,看起来像这样
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": []
请记住,每个级别都有未知数量的兄弟姐妹和孩子。 我想我需要编写一个递归过程,但我无法将其可视化。
答案 0 :(得分:1)
首先,您可能希望您的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;
在评论中,OP提到TDepartment
包含更多字段,但只有问题中的字段应序列化;还必须使用TJSONObject
,并且部门不了解其子女。你可以这样做:
function TDepartment.Serialize2(AllDepartments: TList<TDepartment>): TJSONObject;
var Department: TDepartment;
Subdepartments: TJSONArray;
begin
Result := TJSONObject.Create;
Result.AddPair(TJSONPair.Create('department_id', TJSONNumber.Create(ID)));
Result.AddPair(TJSONPair.Create('department_name', Name));
Result.AddPair(TJSONPair.Create('parent_dept_id', TJSONNumber.Create(ParentDepartmentID)));
Subdepartments := TJSonArray.Create;
for Department in AllDepartments do
begin
if (Department.ParentDepartmentID <> ID) then Continue;
Subdepartments.AddElement(Department.Serialize2(AllDepartments));
end;
Result.AddPair(TJSONPair.Create('subdepartments', Subdepartments));
end;
答案 1 :(得分:0)
我会创建一个并行树结构,保留原始原样。您当前的结构将根据您的需要进行反转,因此您可以扫描当前对象,将它们放在树中。但是在不知道当前结构的情况下,这很难给出示例代码,但是假设所有部门都存在于某种列表中(让我们称之为“部门”)和“根部”#39;部门的父部门ID为零,它会是这样的:
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.
请注意,这仅用于说明目的。您可能不会创建和销毁我所拥有的结构。拥有该结构后,您无疑可以使用当前例程创建JSON记录。