XE3随笔12: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;
时间: 2024-08-07 01:55:47

XE3随笔12:TSuperTableString、TSuperAvlEntry的相关文章

XE3随笔3:访问

测试数据提前加入 Memo1 中: { "name": "张三", /* 注释 */ "age": 33, "sex": true, "weight": 123.456, "tel": ["86-1111111", "86-2222222"], "addresses":{"address":"A省B

XE3随笔20:几个和当前路径相关的新函数

偶然从 SysUtils 里发现了几个路径相关的函数, 以前没见过, 可能是 Delphi XE3 新增的: GetLocaleDirectory(); GetLocaleFile(); LocaleDirectoryExists(); LocaleFileExists(); 应用测试: uses IOUtils; procedure TForm1.FormCreate(Sender: TObject); var   p,f: string;   b: Boolean; begin   {设置与

python随笔12(传递任意数量的实参)

有时候,你预先不知道函数需要接受多少个实参,好在python允许函数从调用语句中收集任意数量的实参. 例如,来看一个制作披萨的函数,它需要接受很多的配料,但你无法预先确定顾客要多少种配料.下面函数只有一个形参*toppings,但不管调用语句提供了多少实参,这个形参都将它们统统收入囊中. def make_pizza(*toppings): """打印顾客点的所有配料""" print(toppings) make_pizza('pepperon

linux随笔(12)---chown和chgrp

一.目的 本文将介绍linux的chown和chgrp命令. chown用来设置文件的拥有者:chgrp用来设置文件的所属组. 本文将选取ubuntu14.04发行版做为描述基础. 二.chown命令 语法:chown user filename 将filename文件的拥有者设置为user. 例如,README.md文件当前的拥有者是zsy,使用chown命令将文件的的拥有者设置为root. 三.chgrp命令 语法:chgrp group filename 将filename的所属组设置为g

XE3随笔2:SuperObject构建JSON

SuperObject 构建一个 JSON 的常用方法: 从字符串.从文件.从流. unit Unit1; interface uses   Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,   Dialogs, StdCtrls; type   TForm1 = class(TForm)     Button1: TButton;     Button2: TButton;     Button

XE3随笔15:使用 IXMLHTTPRequest 简单获取网页源代码

unit Unit1; interface uses   Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,   Dialogs, StdCtrls; type   TForm1 = class(TForm)     Memo1: TMemo;     Button1: TButton;     procedure Button1Click(Sender: TObject);   end; var

yii2阅读随笔12

<?php /** * Checks if a property value is null. * 检查属性值是否为空. * This method will check in the following order and act accordingly: * 此方法将在以下顺序检查并相应地采取行动: * - a property defined by a setter: return whether the property value is null * 通过setter定义的属性:返回是

XE3随笔17:实例 - 模拟 Google 搜索

本例测试效果图: 代码文件: unit Unit1; interface uses   Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,   Dialogs, StdCtrls; type   TForm1 = class(TForm)     Memo1: TMemo;     Edit1: TEdit;     Button1: TButton;     procedure Button1Cl

XE3随笔19:实例 - 借用 Google 实现全文翻译

调用 Google 翻译的地址格式: http://ajax.googleapis.com/ajax/services/language/translate?v=1.0&q=" + 原始文本 + "&langpair=" + 原语言 + "%7C" + 目标语言 返回的数据格式如下, 可以用 responseData.translatedText 简单获取: { "responseData" : {"trans