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

文章目录

    • TStringList 与TStrings的区别
    • 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 用于实际的字符串列表处理。

    例子:

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

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

TStringList 常用方法与属性

  1. 基本用法

    varList: TStringList;i: Integer;
    beginList := 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. 读入字符串

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

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

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

    varList: TStringList;
    beginList := 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;
    beginResult := -AnsiCompareText(List[Index1], List[Index2]);
    end;
    
    procedure TForm1.Button1Click(Sender: TObject);
    varList: TStringList;
    beginList := 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;beginResult := AnsiCompareText(List[Index1], List[Index2]);end;
    

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

  2. 降序排序:

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

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

  3. 按字符串长度排序:

    	function LengthCompareStrings(List: TStringList; Index1, Index2: Integer): Integer;beginResult := 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;
varNum1, Num2: Integer;
begin// 将字符串转换为数字Num1 := StrToIntDef(List[Index1], MaxInt);Num2 := StrToIntDef(List[Index2], MaxInt);// 进行数字比较Result := Num1 - Num2;//如果都不是数字安装默认排序法排序if (Num1 = MaxInt) and (Num2 = MaxInt) thenResult := AnsiCompareText(List[Index1], List[Index2]);
end;

终于正常排序了,Very good.

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

constconstr :String = 'aaa,bbb,ccc,ddd';
varstrs :TStrings;i :Integer;
beginstrs := TStringList.Create;strs.CommaText := constr;for i := 0 to Strs.Count-1 doShowMessage(Strs[i]);
end;

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

constconstr :String = 'aaa\bbb\ccc\ddd';
varstrs :TStrings;i :Integer;
beginstrs := TStringList.Create;strs.Delimiter := '\';strs.DelimitedText := constr;for i := 0 to Strs.Count-1 doShowMessage(Strs[i]);
end;

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

constconstr :String = '"aaa"\"bbb"\"ccc"\"ddd"';
varstrs :TStrings;i :Integer;
beginstrs := TStringList.Create;strs.Delimiter := '\';strs.DelimitedText := constr;for i := 0 to Strs.Count-1 doShowMessage(Strs[i]);
end;

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

再来看一个例子:

constconstr :String = '|aaa|\|bbb|\|ccc|\|ddd|';
varstrs :TStrings;i :Integer;
beginstrs := TStringList.Create;strs.Delimiter := '\';strs.QuoteChar := '|';strs.DelimitedText := constr;for i := 0 to Strs.Count-1 doShowMessage(Strs[i]);
end;

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

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

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

constconstr :String = '0=aaa,1=bbb,2=ccc,3=ddd';
varstrs :TStrings;i :Integer;
beginstrs := TStringList.Create;strs.CommaText := constr;for i := 0 to strs.Count-1 dobeginShowMessage(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(在原文的基础上重新整理修改)

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/638282.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Win10升级Win11后卡顿了?

目录 关闭动画效果 任务栏居中改为居左 调整外观和性能 其他 当你看到最后,还知道哪些升级WIN11后必做的优化呢?欢迎在评论区分享出来!❤️ win11上市目前也有一段时间了,想必很多大家都已经进行更新了。新的系统确实更加简洁…

安规电容的知识

1、常见安规电容有哪些? 一般我们所说的安规电容也就有两种,一种就是X安规电容(X1/X2/X3安规电容),还有一种是Y电容(最常见的是Y1和Y2安规电容)。 2、x电容的位置 火线零线间的是X电容。x电容用…

Git将某个文件合并到指定分支

企业开发中&#xff0c;经常会单独拉分支去做自己的需求开发&#xff0c;但是某些时候一些公共的配置我们需要从主线pull&#xff0c;这时候整个分支merge显然不合适 1.切换至待合并文件的分支 git checkout <branch>2.将目标分支的单个文件合并到当前分支 git checkou…

力扣刷MySQL-第三弹(详细讲解)

&#x1f389;欢迎您来到我的MySQL基础复习专栏 ☆* o(≧▽≦)o *☆哈喽~我是小小恶斯法克&#x1f379; ✨博客主页&#xff1a;小小恶斯法克的博客 &#x1f388;该系列文章专栏&#xff1a;力扣刷题讲解-MySQL &#x1f379;文章作者技术和水平很有限&#xff0c;如果文中出…

JVM中的垃圾收集算法

标记-清除算法 首先标记出所有需要回收的对象&#xff0c;在标记完成后&#xff0c;统一回收掉所有被标记的对象&#xff0c;也可以反过来&#xff0c;标记存活的对象&#xff0c;统一回收所有未被标记的对象。标记过程就是对象是否属于垃圾的判定过程 缺点 第一个是执行效率…

【算法基础 数学】快速幂求逆元(逆元、扩展欧几里得定理、小费马定理)

文章目录 为什么需要逆元逆元的概念1.单位元2.逆元3.模乘的单位元4.模乘的逆元 开始求逆元1.扩展欧几里得定理2.费马小定理 原文链接 为什么需要逆元 首先&#xff0c;在算法竞赛中&#xff0c;很多情况下会遇到数值很大的数据&#xff0c;这个时候&#xff0c;题目往往会让我…

C# 获取QQ会话聊天信息

目录 利用UIAutomation获取QQ会话聊天信息 效果 代码 目前遇到一个问题 其他解决办法 利用UIAutomation获取QQ会话聊天信息 效果 代码 AutomationElement window AutomationElement.FromHandle(get.WindowHwnd); AutomationElement QQMsgList window.FindFirst(Tr…

4.postman批量运行及json、cvs文件运行

一、批量运行collection 1.各个接口设置信息已保存&#xff0c;在collection中点击run collection 2.编辑并运行集合 集合运行时&#xff0c;单独上传图片时报错。需修改postman设置 二、csv文件运行 可新建记事本&#xff0c;输入测试数据&#xff0c;后另存为新的文本文件&…

Pytest 结合 Allure 生成测试报告

测试报告在项目中是至关重要的角色&#xff0c;一个好的测试报告&#xff1a; 可以体现测试人员的工作量&#xff1b; 开发人员可以从测试报告中了解缺陷的情况&#xff1b; 测试经理可以从测试报告中看到测试人员的执行情况及测试用例的覆盖率&#xff1b; 项目负责人可以通过…

c#之函数

1. 定义一个函数,用来取得数字的和,但是数字的个数不确定 (1) class Program{static int Sum(int[] array){int num 0;for (int i 0; i < array.Length; i){num num array[i];}return num;}static void Main(string[] args){int sum Sum(new int[]{12,13,34,5,68,9,9…

echarts-wordcloud词云

echarts-wordcloud是基于echarts的一个插件&#xff0c;所以我们要首先安装echarts包&#xff0c;然后再安装echarts-wordcloud的包&#xff0c;这里我的练习项目安装的版本&#xff1b;当然&#xff0c;你可以随意安装你需要的版本&#xff1b; “echarts”: “^5.3.3”, “ec…

Hive架构设计

我们知道MapReduce和Spark它们提供了高度抽象的编程接口便于用户编写分布式程序,它们具有极好的扩展性和容错性,能够处理超大规模的数据集。这些计算引擎提供了面向高级语言(比如Java,Python等)的编程接口,然而,考虑到分布式程序编写的复杂性,直接使用这些编程接口实现…

Django中解决跨域问题

同源策略&#xff08;Same origin policy&#xff09;是一种约定&#xff0c;它规定了 请求的url地址,必须与浏览器上的url地址处于同域上,也就是域名,端口,协议相同&#xff0c;如果不一致&#xff0c;请求会发送成功&#xff0c;后端会正常响应&#xff0c;但是浏览器会拦截 …

面试2024.1.20

简单介绍下你做的项目。 这个神领物流项目是一个前后端分离的项目&#xff0c;前段他有3个客户端&#xff08;用户端为微信小程序、司机端和快递员端为app&#xff09;一个管理端&#xff08;pc&#xff09;&#xff0c;后端用的技术栈用的是SpringAlibabaCloud、数据库用的是M…

【精选】中间件 tomcat漏洞复现

&#x1f36c; 博主介绍&#x1f468;‍&#x1f393; 博主介绍&#xff1a;大家好&#xff0c;我是 hacker-routing &#xff0c;很高兴认识大家~ ✨主攻领域&#xff1a;【渗透领域】【应急响应】 【python】 【VulnHub靶场复现】【面试分析】 &#x1f389;点赞➕评论➕收藏…

JRTP实时音视频传输(2)-使用TCP通信的案例

环境搭建等参考&#xff1a;JRTP实时音视频传输(1)-必做的环境搭建与demo测试 1.创建自己的demo 先将example1拷贝为myclienttcp.cpp和myservertcp.cpp cp example1.cpp myclienttcp.cpp cp example1.cpp myservertcp.cpp 改写jrtplib/JRTPLIB/examples/CMakeLists.txt&…

79、avx2 向量指令集优化卷积运算

上一节 介绍了 avx2 向量指令集中的 load/store 操作,本节介绍如何使用 avx2 的向量指令集来实现乘累加运算。 因为我们实战中用到的 resnet50 神经网络中,卷积运算在整个模型中的比例占据是相当高,而卷积运算的核心计算就是乘累加计算。因此,只要将最核心的乘累加计算效率…

2024成都线路板展览会|全国线路板展

时 间&#xff1a;2024年7月17&#xff5e;19日 地 点&#xff1a;成都世纪城新国际会展中心 ◆ 》》》展会概况&#xff1a; 电路板是电子产品的关键电子互联件&#xff0c;被誉为“电子产品之母”。电路板行业作为电子信息产业中重要的组成部分&#xff0c;受到国家产…

怎么从视频中提取动图?一个方法快速提取gif

视频以连续的方式播放一系列图像帧&#xff0c;通过每秒播放的帧数&#xff08;帧率&#xff09;来创做&#xff0c;由于GIF动图则以循环播放一系列静态图像帧的方式展现动画效果。由于视频的优势在于流畅的动画、丰富的细节和长时间播放&#xff0c;因此常用于电影、电视节目、…

React Hooks 基本使用

背景 class 组件如果业务复杂&#xff0c;很难拆分和重构&#xff0c;很难测试&#xff1b;相同业务逻辑分散到各个方法中&#xff0c;逻辑混乱逻辑复用像HOC、Render Props&#xff0c;不易理解&#xff0c;学习成本高React提倡函数式编程&#xff0c;函数更易拆分&#xff0…