JSON 之 SuperObject(11): TSuperTableString、TSuperAvlEntry


通过 ISuperObject.AsObject 可获取一个 TSuperTableString 对象.

TSuperTableString 的常用属性: count、GetNames、GetValues

var

  jo: ISuperObject;

  jts: TSuperTableString;

begin

  jo := SO('{A:1, B:2, C:3, D:{x:4, y:5, z:6}}');



  jts := jo.AsObject;

  ShowMessage(IntToStr(jts.count));    // 4

  ShowMessage(jts.GetNames.AsString);  // ["D","C","B","A"]

  ShowMessage(jts.GetValues.AsString); // [{"z":6,"y":5,"x":4},3,2,1]



  jts := jo['D'].AsObject;

  ShowMessage(IntToStr(jts.count));    // 3

  ShowMessage(jts.GetNames.AsString);  // ["z","y","x"]

  ShowMessage(jts.GetValues.AsString); // [6,5,4]

end;


 
   

JSON 本质就是一个二叉树(SuperObject 支持 32 层深度, 足够了);

二叉树的每个节点主要表示一个 Name:Value; 其中的 Name 是字符串, Value 可能是个字符串、整数、数组或另一个 ISuperObject, 所以 Value 的类型只能是 ISuperObject.

描述这个节点的类是 TSuperAvlEntry, 我们可以从一个 TSuperTableString 中枚举出当前层及的每个 TSuperAvlEntry.

var

  jo, io: ISuperObject;

  item: TSuperAvlEntry;

begin

  jo := SO('{A:1, B:2, C:3, D:{x:4, y:5, z:6}}');



  {从 TSuperTableString(这里是用 jo.AsObject 获取)中枚举 TSuperAvlEntry}

  Memo1.Clear;

  for item in jo.AsObject do

    Memo1.Lines.Add(Format('Name: %s; Value: %s', [item.Name, item.Value.AsString]));



  {直接从 ISuperObject 中枚举 "子ISuperObject"}

  Memo1.Lines.Add(EmptyStr);

  for io in jo do

    Memo1.Lines.Add(Format('Value: %s', [io.AsString]));

end;


 
   

上面的遍历都没有深入下去, 要彻底深入地遍历需要写回调函数.

下面写了两个回调函数, 第一个没有考虑数组中的对象:

uses SuperObject;



//使用回调的遍历过程之一: 没考虑数组中的对象

procedure Proc1(jo: ISuperObject; var List: TStrings);

var

  item: TSuperAvlEntry;

begin

  for item in jo.AsObject do

    if item.Value.DataType = stObject then

      Proc1(item.Value, List) {如果是对象就回调}

    else {不是对象就添加到列表}

      List.Add(Format('%s : %s', [item.Name, item.Value.AsString])); 

end;



//使用回调的遍历过程之二:

procedure Proc2(jo: ISuperObject; var List: TStrings);

var

  i: Integer;

  item: TSuperAvlEntry;

begin

  for item in jo.AsObject do

  begin

    if item.Value.DataType = stObject then

      Proc2(item.Value, List) {如果是对象就回调}

    else begin {不是对象就添加到列表}

      List.Add(Format('%s : %s', [item.Name, item.Value.AsString]));

      if item.Value.DataType = stArray then begin {如果是数组, 看看里面是不是有对象}

        for i := 0 to item.Value.AsArray.Length - 1 do

          if item.Value.AsArray[i].DataType = stObject then

            Proc2(item.Value.AsArray[i], List); {如果是对象就再回调}

      end;

    end;

  end;

end;



//调用测试

procedure TForm1.Button1Click(Sender: TObject);

var

  jo: ISuperObject;

  List: TStrings;

begin

  jo := SO('{A:1, B:2, C:3, D:[4, 5, {X:6}, {Y:[7,8,{m:9}]}]}');



  List := TStringList.Create;

  Proc1(jo, List);

  ShowMessage(List.Text);



  List.Clear;

  Proc2(jo, List);

  ShowMessage(List.Text);



  List.Free;

end;


 
   

你可能感兴趣的:(String)