【Delphi 基础知识 22】TStringList 的详细用法


TStringList 类在Delphi中会经常使用到,我们这里一起来看看 TStringList 的详细用法.

TStringList 与TStrings的区别

TStringListTStrings 都是 Delphi 编程语言中用于处理字符串列表的类。它们之间有一些区别,但也有关联。让我们先看看它们的关系:

  1. TStrings 类:
  • TStrings 是一个抽象类,它定义了一组处理字符串列表的基本方法和属性。这个类提供了对字符串列表的访问、修改和管理的基本功能,但它本身不能被实例化。
  • TStringListTStrings 的一个具体实现,因此它可以被实例化。
  1. TStringList 类:
  • TStringList 继承自 TStrings,因此它包含了 TStrings 中定义的所有方法和属性,并在此基础上添加了一些额外的功能。
  • TStrings 的一个实现,用于实际的字符串列表管理。
  • 支持排序、查找、插入等功能,使其在处理大量字符串时更加高效。

简而言之,TStringListTStrings 的一个特定实现,提供了更多的功能和性能优化。以下是一些具体的区别:

  • 性能:
    TStringList 在处理大型字符串列表时通常更快,因为它包含了一些优化算法,比如排序和查找。

  • 功能:
    TStringList 提供了一些额外的功能,如排序、查找、存储对象等,而 TStrings 只提供了基本的字符串列表管理功能。

  • 实例化:
    TStrings 不能直接实例化,而必须通过派生类(如 TStringList)来实现。

  • 用法:
    TStrings 通常用作函数参数类型或返回类型,而 TStringList 用于实际的字符串列表处理。

    例子:

    var
      MyList: TStringList;
    begin
      // 创建 TStringList 对象
      MyList := TStringList.Create;
      
      // 使用 TStrings 的方法
      MyList.Add('Item 1');
      MyList.Add('Item 2');
    
      // 使用 TStringList 的方法
      MyList.Sort;
      
      // 释放对象
      MyList.Free;
    end;
    

在实际编码中,通常会使用 TStringList,因为它提供了更多的功能和更好的性能。

TStringList 常用方法与属性

  1. 基本用法

    var
      List: TStringList;
      i: Integer;
    begin
      List := TStringList.Create;
      List.Add('Strings1');           {
         添加}
      List.Add('Strings2');
      List.Exchange(0,1);             {
         置换}
      List.Insert(0,'Strings3');      {
         插入}
      i := List.IndexOf('Strings1');  {
         第一次出现的位置}
      List.Sort;                      {
         排序}
      List.Sorted := True;           {
         指定排序}
      List.Count;                     {
         总数}
      List.Text;                      {
         文本集合}
      List.Delete(0);                 {
         删除, 0是第一个数据}
      List.LoadFromFile('c:\tmp.txt');{
         打开}
      List.SaveToFile('c:\tmp.txt');  {
         保存}
      List.Clear;                     {
         清空}
      List.Free;                      {
         释放}
    end;
    
  2. 读入字符串

    var
      List: TStringList;
    begin
      List := TStringList.Create;
      List.CommaText := 'aaa,bbb,ccc,ddd';
      //相当于: List.Text := 'aaa' + #13#10 + 'bbb' + #13#10' + 'ccc' + '#13#10' + 'ddd';
      ShowMessage(IntToStr(List.Count));  //4
      ShowMessage(List[0]);  //aaa
      List.Free;
    end;
    
  3. 分隔符操作

    var
      List: TStringList;
    begin
      List := TStringList.Create;
      List.Delimiter := '|';
      List.DelimitedText := 'aaa|bbb|ccc|ddd';
       ShowMessage(IntToStr(List.Count));  //4
      ShowMessage(List[0]);  //aaa
       List.Free;
    end;
    
  4. 类似的哈希表操作法

    var
      List: TStringList;
    begin
      List := TStringList.Create;
      List.Add('aaa=111');
      List.Add('bbb=222');
      List.Add('ccc=333');
      List.Add('ddd=444');
      ShowMessage(List.Names[1]);  //bbb
      ShowMessage(List.ValueFromIndex[1]);  //222
      ShowMessage(List.Values['bbb']);  //222
      //ValueFromIndex 可以赋值:
      List.ValueFromIndex[1] := '2';
      ShowMessage(List[1]);  //bbb=2
      //可以通过 Values 赋值:
      List.Values['bbb'] := '22';
      ShowMessage(List[1]);  //bbb=22
      List.Free;
    end;
    
  5. 避免重复值

    var
      List: TStringList;
    begin
      List := TStringList.Create;
       List.Add('aaa');
      List.Sorted := True;  //需要先指定排序
      List.Duplicates := dupIgnore;  //如有重复值则放弃 
      List.Add('aaa');
      ShowMessage(List.Text);  //aaa
      //Duplicates 有3个可选值:
      //dupIgnore: 放弃;
      //dupAccept: 结束;
      //dupError: 提示错误.
      List.Free;
    end;
    
  6. 排序与倒排序

    //排序函数
    function DescCompareStrings(List: TStringList; Index1, Index2: Integer): Integer;
    begin
      Result := -AnsiCompareText(List[Index1], List[Index2]);
    end;
    
    procedure TForm1.Button1Click(Sender: TObject);
    var
      List: TStringList;
    begin
      List := TStringList.Create;
      List.Add('bbb');
      List.Add('ccc');
      List.Add('aaa'); 
      //没有排序
      ShowMessage(List.Text);  //bbb ccc aaa 
      //正排序
      List.Sort;
      ShowMessage(List.Text);  //aaa bbb ccc
      //倒排序
      List.CustomSort(DescCompareStrings);  //调用排序函数
      ShowMessage(List.Text);  //ccc bbb aaa
      //假如
      List.Sorted := True;
      List.Add('999');
      List.Add('000');
      List.Add('zzz');
      ShowMessage(List.Text);  //000 999 aaa bbb ccc zzz
    end;
    

这里List.CustomSort(DescCompareStrings);是自定义排序函数,我们可以自己设计排序函数

列举几个常用的排序规则的示例:

  1. 升序排序(默认规则):

    	function AscendingCompareStrings(List: TStringList; Index1, Index2: Integer): Integer;
    	begin
    	  Result := AnsiCompareText(List[Index1], List[Index2]);
    	end;
    

    这是默认的升序排序规则。使用 AnsiCompareText 函数比较字符串,返回标准的升序排序。

  2. 降序排序:

    	function DescendingCompareStrings(List: TStringList; Index1, Index2: Integer): Integer;
    	begin
    	  Result := -AnsiCompareText(List[Index1], List[Index2]);
    	end;
    

    这是降序排序规则。与升序相比,返回值取反,实现降序排序。

  3. 按字符串长度排序:

    	function LengthCompareStrings(List: TStringList; Index1, Index2: Integer): Integer;
    	begin
    	  Result := Length(List[Index1]) - Length(List[Index2]);
    	end;
    

    这个规则按字符串长度升序排序。如果你希望降序排序,可以取反返回值。

  4. 自定义规则(示例):

    function CustomCompareStrings(List: TStringList; Index1, Index2: Integer): Integer;
    begin
      // 自定义比较规则,根据你的需求实现
      // 返回负值、零、正值分别表示小于、等于、大于的关系
    end;
    

    这是一个占位的自定义比较规则,你可以在函数体内根据具体需求实现自定义的比较逻辑。

使用这些规则时,只需将相应的比较函数传递给 CustomSort 方法,例如:

MyList.CustomSort(AscendingCompareStrings); // 升序排序
MyList.CustomSort(DescendingCompareStrings); // 降序排序
MyList.CustomSort(LengthCompareStrings);     // 按长度排序
MyList.CustomSort(CustomCompareStrings);     // 自定义规则

我们自己构造一个排序算法,比如我们经常会遇到8,9,10这样的数字会被排序成10,8,9。必须要改成08,09,10才可以正常排序,非常麻烦。现在自己设计一个排序函数:

function NumericSort(List: TStringList; Index1, Index2: Integer): Integer;
var
  Num1, Num2: Integer;
begin
  // 将字符串转换为数字
  Num1 := StrToIntDef(List[Index1], MaxInt);
  Num2 := StrToIntDef(List[Index2], MaxInt);
  // 进行数字比较
  Result := Num1 - Num2;
  //如果都不是数字安装默认排序法排序
  if (Num1 = MaxInt) and (Num2 = MaxInt) then
    Result := AnsiCompareText(List[Index1], List[Index2]);
end;

终于正常排序了,Very good.

现在来讨论它的一些高级的用法。
先看第一个:CommaText。怎么用呢?用代码说话:

const
	constr :String = 'aaa,bbb,ccc,ddd';
var
	strs :TStrings;
	i :Integer;
begin
	strs := TStringList.Create;
	strs.CommaText := constr;
	for i := 0 to Strs.Count-1 do
	    ShowMessage(Strs[i]);
end;

执行了这段代码后,可以看到ShowMessage显示出来的分别是:aaa bbb ccc ddd。
也就是说,strs.CommaText := constr这一句的作用,就是把一个字符串以’,'为分割符,分段添加到TStrings中。
那么如果不是以, 来分割,又该怎么做呢?现在看第二个例子。使用Delimiter和DelimitedText。

const
  constr :String = 'aaa\bbb\ccc\ddd';
var
  strs :TStrings;
  i :Integer;
begin
  strs := TStringList.Create;
  strs.Delimiter := '\';
  strs.DelimitedText := constr;
  for i := 0 to Strs.Count-1 do
     ShowMessage(Strs[i]);
end;

可以看到, 显示的效果和第一个例子是一模一样的。解释一下:
Delimiter为分隔符,默认为, DelimitedText就是按Delimiter为分隔符的一个串,得到赋值后回把这个字符串按Delimiter的字符添加到TStrings中。
说到这里,有想起一个属性,QuoteChar。其默认值为:‘"’(不包括单引号)
有何用呢?看例子:

const
  constr :String = '"aaa"\"bbb"\"ccc"\"ddd"';
var
  strs :TStrings;
  i :Integer;
begin
  strs := TStringList.Create;
  strs.Delimiter := '\';
  strs.DelimitedText := constr;
  for i := 0 to Strs.Count-1 do
      ShowMessage(Strs[i]);
end;

显示出来的仍然是aaa bbb ccc ddd。为什么不是:“aaa” “bbb” “ccc” "ddd"呢?

再来看一个例子:

const
  constr :String = '|aaa|\|bbb|\|ccc|\|ddd|';
var
  strs :TStrings;
  i :Integer;
begin
  strs := TStringList.Create;
  strs.Delimiter := '\';
  strs.QuoteChar := '|';
  strs.DelimitedText := constr;
  for i := 0 to Strs.Count-1 do
      ShowMessage(Strs[i]);
end;

显示出来的又是aaa bbb ccc ddd。对比一下,应该不难明白吧?QuoteChar 不给他指定的话默认就是"
但是还要多说一句,当Delimiter为, 而QuoteChar为" 时,DelimitedText和CommaText是同等的。

这里注意Delimiter是一个Char,他只能是一个字符,如果要分割 ‘aaa----bbb----ccc----ddd’这样的字符串,可以用替换函数StringReplace---替换成-在处理。

最后要说的三个是:Names & Values & ValueFromIndex。
看看下面的代码:

const
	constr :String = '0=aaa,1=bbb,2=ccc,3=ddd';
var
	strs :TStrings;
	i :Integer;
begin
	strs := TStringList.Create;
	strs.CommaText := constr;
	for i := 0 to strs.Count-1 do
	begin
	    ShowMessage(strs.Names);
	    ShowMessage(strs.Values[strs.Names]);
	    ShowMessage(strs.ValueFromIndex);
	end;
end;

通过这个例子不难看出:
这个时候strs中的内容是:
0=aaa
1=bbb
2=ccc
3=ddd

而Names中则是:
0
1
2
3

在Values中则是:
aaa
bbb
ccc
ddd

下面的代码中空格也会被当做分割符

List.Delimiter := '|'; 
List.DelimitedText := 'aaa|bb b|ccc|ddd'; 

我们需要设置强制分隔符

// 将严格按照预先设定的分隔符去分隔字符
List.StrictDelimiter:= True;
List.Delimiter := '|';
List.DelimitedText := 'aaa|bb b|ccc|ddd';

原文链接:https://blog.csdn.net/zisongjia/article/details/53784120(在原文的基础上重新整理修改)

相关推荐

  1. Delphi 基础知识 22TStringList 详细

    2024-01-21 20:38:04       27 阅读
  2. Delphi 基础知识 24】Format函数

    2024-01-21 20:38:04       34 阅读
  3. Delphi 基础知识 29】ListBox控件详细使用

    2024-01-21 20:38:04       32 阅读
  4. Delphi 基础知识 31】Timer控件详细使用

    2024-01-21 20:38:04       25 阅读
  5. Delphi 基础知识 8】常用运算符

    2024-01-21 20:38:04       40 阅读
  6. Delphi 基础知识 3】每个单元功能

    2024-01-21 20:38:04       38 阅读
  7. Delphi 基础知识 17】注释代码几种方法

    2024-01-21 20:38:04       30 阅读
  8. docker 相关知识

    2024-01-21 20:38:04       30 阅读
  9. Delphi 基础知识 4】类是如何被实例化?

    2024-01-21 20:38:04       37 阅读

最近更新

  1. TCP协议是安全的吗?

    2024-01-21 20:38:04       16 阅读
  2. 阿里云服务器执行yum,一直下载docker-ce-stable失败

    2024-01-21 20:38:04       16 阅读
  3. 【Python教程】压缩PDF文件大小

    2024-01-21 20:38:04       15 阅读
  4. 通过文章id递归查询所有评论(xml)

    2024-01-21 20:38:04       18 阅读

热门阅读

  1. CSS Day10

    CSS Day10

    2024-01-21 20:38:04      26 阅读
  2. Linux设置nginx开机自启动

    2024-01-21 20:38:04       33 阅读
  3. C# 字符串(String)

    2024-01-21 20:38:04       36 阅读
  4. datasets的一些使用技巧

    2024-01-21 20:38:04       33 阅读
  5. 【智驾未来】低代码开发:加速创新交融的利器

    2024-01-21 20:38:04       30 阅读
  6. C# 程序结构

    2024-01-21 20:38:04       30 阅读
  7. 【工业智能】VSB Power Line Fault Detection-chapter2

    2024-01-21 20:38:04       31 阅读
  8. 生产告警JVM内存使用率超过80%告警问题排查

    2024-01-21 20:38:04       33 阅读