写了一个字符串的二维表: TSta
2021-05-01 00:28
856 查看
写了一个字符串的二维表: TSta
STA 单元 (用到 System.SysUtils.TStringHelper):
unit STA; interface uses System.SysUtils, System.Classes; type TSta = record FSeparator: Char; FArr: TArray<TArray>; constructor Create(const aStr: string; const aSeparator: Char = ';'); overload; class operator Explicit(const aStr: string): TSta; class operator Implicit(const aStr: string): TSta; function GetItem(i,j: Integer): string; procedure SetItem(i,j: Integer; Value: string); function GetRow(i: Integer): string; procedure SetRow(i: Integer; Value: string); procedure SetSeparator(const Value: Char); function GetRowCount: Integer; procedure SetRowCount(const Value: Integer); function ToString: string; procedure Clear; procedure LoadFromFile(const aFileName: string; aEncoding: TEncoding = nil); procedure SaveToFile(const aFileName: string; aEncoding: TEncoding = nil); property Separator: Char read FSeparator write SetSeparator; property RowCount: Integer read GetRowCount write SetRowCount; property Items[i,j: Integer]: string read GetItem write SetItem; default; property Rows[i: Integer]: string read GetRow write SetRow; end; implementation { TSta } procedure TSta.Clear; begin SetLength(FArr, 0); end; constructor TSta.Create(const aStr: string; const aSeparator: Char); var tArr: TArray; i: Integer; begin FSeparator := aSeparator; tArr := aStr.Split([sLineBreak], ExcludeEmpty); SetLength(FArr, Length(tArr)); for i := 0 to High(FArr) do begin FArr[i] := tArr[i].Split([FSeparator]); end; end; function TSta.GetItem(i,j: Integer): string; begin Result := ''; if (i < 0) or (j < 0) then Exit; if (i < Length(FArr)) and (j < Length(FArr[i])) then Result := FArr[i, j].Trim; end; procedure TSta.SetItem(i,j: Integer; Value: string); var k,n: Integer; begin if Value.Trim = '' then Exit; if Length(FArr) = 0 then FSeparator := ';'; n := Length(FArr); if i >= n then begin SetLength(FArr, i+1); for k := n to i - 1 do SetLength(FArr[k], 1); end; if j >= Length(FArr[i]) then SetLength(FArr[i], j+1); FArr[i,j] := Value.Trim; end; function TSta.GetRow(i: Integer): string; begin Result := ''; if i < Length(FArr) then begin if Length(FArr[i]) > 0 then Result := Result.Join(FSeparator, FArr[i]); end; end; function TSta.GetRowCount: Integer; begin Result := Length(FArr); end; procedure TSta.SetRow(i: Integer; Value: string); var k,n: Integer; begin if Value.Trim = '' then Exit; if Length(FArr) = 0 then FSeparator := ';'; n := Length(FArr); if i >= n then begin SetLength(FArr, i+1); for k := n to i - 1 do SetLength(FArr[k], 1); end; FArr[i] := Value.Split([FSeparator]); end; procedure TSta.SetRowCount(const Value: Integer); begin SetLength(FArr, Value); end; procedure TSta.SetSeparator(const Value: Char); begin FSeparator := Value; if Length(FArr) = 0 then SetLength(FArr, 1); //直接使用索引赋值时, 会根据 Length(FArr) 是否为 0 来设置默认分隔符 end; class operator TSta.Explicit(const aStr: string): TSta; begin Result := TSta.Create(aStr); end; class operator TSta.Implicit(const aStr: string): TSta; begin Result := TSta.Create(aStr); end; function TSta.ToString: string; var i: Integer; begin if Length(FArr) = 0 then Exit(''); Result := Rows[0]; for i := 1 to High(FArr) do Result := Result + sLineBreak + Rows[i]; end; procedure TSta.LoadFromFile(const aFileName: string; aEncoding: TEncoding); begin if not FileExists(aFileName) then Exit; if aEncoding = nil then aEncoding := TEncoding.Default; with TStringList.Create do begin LoadFromFile(aFileName, aEncoding); Self := Text; Free; end; end; procedure TSta.SaveToFile(const aFileName: string; aEncoding: TEncoding); begin if aEncoding = nil then aEncoding := TEncoding.Default; with TStringList.Create do begin Text := Self.ToString; SaveToFile(aFileName, aEncoding); Free; end; end; end.
测试:
uses STA; procedure TForm1.Button1Click(Sender: TObject); var S: TSta; str: string; begin S := 'AAA;BBB;CCC' + sLineBreak + '111;222;333'; //可以从字符串隐式或显式地转换到 TSta str := S[0,0]; //AAA str := S[1,2]; //333 str := S[9,9]; //越界读取返回空 str := S.Rows[0]; //AAA;BBB;CCC str := S.Rows[1]; //111;222;333 str := S.ToString; //AAA;BBB;CCC //111;222:333 S.Separator := '&'; //更换分隔符; 默认是分号; 也可在 Create 时指定 str := S.Rows[1]; //111&222&333 ShowMessage(str); end; procedure TForm1.Button2Click(Sender: TObject); var S: TSta; str: string; begin S[0,0] := 'aaa'; S[0,1] := 'bbb'; S[0,2] := 'ccc'; S[2,2] := 'zzz'; str := S.ToString; //aaa;bbb;ccc // //;;zzz S.Rows[1] := '111;222;333'; str := S.ToString; //aaa;bbb;ccc //111;222;333 //;;zzz // ShowMessage(str); end; procedure TForm1.Button3Click(Sender: TObject); const nFileName = 'c:\temp\staTest.txt'; var S: TSta; str: string; begin S[0,0] := 'aaa'; S[0,1] := 'bbb'; S[0,2] := 'ccc'; S[1,0] := '111'; S[1,1] := '222'; S[1,2] := '333'; S[1,3] := '444'; S.SaveToFile(nFileName); //保存到文件 S.Clear; str := S[0,0]; //空 // ShowMessage(str); S.LoadFromFile(nFileName); //从文件读取 str := S[0,0]; //aaa str := S.Rows[0]; //aaa;bbb;ccc // ShowMessage(str); end;
相关文章推荐
- 覆盖、再覆盖
- 记一次失败的Perl + Nginx + FastCGI 配置过程
- 执行 Application.Terminate 后, OnDestroy 中的代码还会执行
- Perl Dancer 学习(一)
- 关于字符串, 之前没这样用过
- 以接口为主导的设计中, 我在使用的框架模式
- 结合领域驱动设计的SOA分布式软件架构
- 获取程序自身大小的函数
- 捕捉 midi 输入消息的基本程序
- Delphi XE2 之 FireMonkey 入门(9) - TBitmap
- C#综合揭秘——细说进程、应用程序域与上下文之间的关系C#综合揭秘——细说多线程(下)”
- WCF揭秘——共享数据契约
- 使用泛型, 写一个为任意类型的动态数组添加元素的方法
- 准备理一下菜单和工具栏相关的组件
- 发现 TSplitter 在嵌套时不好用, 索性写了个替代品
- Action 相关组件
- WF工作流与Web服务的相互调用 —— WF与WCF互相调用(利用ReceiveActivity把WF发布为WCF)
- WF工作流与Web服务的相互调用 —— 以InvokeWebServiceActivity在Workflow工作流调用Web服务
- WF工作流与Web服务的相互调用 —— 通过Web服务调用Workflow工作流(开发持久化工作流)
- WF工作流与Web服务的相互调用 —— 通过Web服务调用Workflow工作流(基础实例)