问题标签 [tstringlist]

For questions regarding programming in ECMAScript (JavaScript/JS) and its various dialects/implementations (excluding ActionScript). Note JavaScript is NOT the same as Java! Please include all relevant tags on your question; e.g., [node.js], [jquery], [json], [reactjs], [angular], [ember.js], [vue.js], [typescript], [svelte], etc.

0 投票
3 回答
16775 浏览

delphi - 如何让 TStringList 在 Delphi 中以不同方式排序

我有一个简单的 TStringList。我对它做了一个 TStringList.Sort 。

然后我注意到下划线“_”排在大写字母“A”之前。这与对相同文本进行排序并在 A 之后排序 _ 的第三方包形成对比。

根据 ANSI 字符集,AZ 是字符 65 - 90,_ 是 95。所以看起来 3rd 方包使用该顺序,而 TStringList.Sort 不是。

我深入研究了 TStringList.Sort 的内容,它使用 AnsiCompareStr(区分大小写)或 AnsiCompareText(不区分大小写)进行排序。我尝试了两种方法,将我的 StringList 的 CaseSensitive 值设置为 true,然后设置为 false。但在这两种情况下,“_”都排在第一位。

我无法想象这是 TStringList 中的一个错误。所以这里一定有其他我没有看到的东西。那可能是什么?

我真正需要知道的是如何让我的 TStringList 进行排序,使其与另一个包的顺序相同。

作为参考,我使用的是 Delphi 2009,并且在我的程序中使用了 Unicode 字符串。


所以这里的最终答案是用你想要的任何东西(例如非 ansi 比较)覆盖 Ansi 比较,如下所示:

0 投票
2 回答
2491 浏览

delphi - 对字符串列表进行排序:仅移动或交换项目

在 Delphi / Pascal 中,我想按字母顺序对 TStringList 进行排序。但是为了这个目的,我只能使用以下两种方法:

移动:将字符串从一个索引位置移动到另一个索引位置,并根据需要移动其他字符串。

交换:交换列表中的两个字符串,由它们的索引位置标识。

我怎么能这样做?我的想法是用一个循环遍历所有项目,然后是这样的:

  1. lastFirstLetter := Copy(CurrentItem, 1, 1)
  2. 转到下一项
  3. currentFirstLetter := Copy(CurrentItem, 1, 1)
  4. 如果 ord(currentFirstLetter) < ord(lastFirstLetter) then exchange(lastItem, currentItem)

使用这两种方法对 StringList 进行排序的最快方法是什么?顺便说一下,我不能使用 sort 方法和 sorted 属性。

0 投票
1 回答
835 浏览

windows - 比较和排序 Unicode 文件名

为 Unicode 实用程序和界面使用 Delphi 2007 和 TMS 组件(升级到 Delphi 2009 以支持 Unicode 不是一种选择)。

我将文件名列表存储在字符串列表(TTntStringList)中。它已排序且不区分大小写。默认排序例程使用 CompareStringW(LOCALE_USER_DEFAULT, NORM_IGNORECASE, ...) 来比较字符串(查找也是如此)。但是,这是一个问题,因为这会将 dummyss.txt 等同于 dummyß.txt(例如),但在 NTFS 上,将这两个文件放在同一个文件夹中是完全合法的,即它们被视为不同的名称。

我的理解是,在 Vista 和更新版本上,比较文件名的正确方法是使用 CompareStringOrdinal。这个对吗?

在 Vista 之前的系统上,正确的方法是什么?我相信它应该是 CompareStringW(LOCALE_INVARIANT, ...) 但我不完全确定。

谢谢

0 投票
7 回答
13094 浏览

delphi - Delphi中的TStringList,动态数组还是链表?

我有一个选择。

我有许多需要存储和访问的已排序字符串。看起来我可以选择使用:

  1. 一个 TStringList

  2. 字符串的动态数组,以及

  3. 字符串的链接列表(单链接)

    艾伦在他的评论中建议我也添加选择:

  4. TList<string>

在什么情况下,这些中的每一个都比其他的更好?

哪个最适合小型列表(10 项以下)?

哪个最适合大型列表(超过 1000 个项目)?

哪个最适合大型列表(超过 1,000,000 个项目)?

哪种方法可以最大程度地减少内存使用?

哪个是最好的,以最大限度地减少加载时间以在最后添加额外的项目?

从头到尾访问整个列表的访问时间最小化是什么?

在此基础上(或任何其他基础上),哪种数据结构更可取?

作为参考,我使用的是 Delphi 2009。


Dimitry 在评论中说:

描述你的任务和数据访问模式,然后就有可能给你一个准确的答案

好的。我有一个包含大量数据的家谱程序。

对于每个人,我都有许多事件和属性。我将它们存储为短文本字符串,但每个人都有很多,范围从 0 到几百。我有成千上万的人。我不需要随机访问它们。我只需要将它们作为多个字符串以已知顺序关联到每个人。这是我成千上万的“小清单”的情况。它们需要时间来加载和使用内存,如果我需要它们全部需要时间来访问(例如导出整个生成的报告)。

然后我有一些更大的列表,例如我的“虚拟”树视图的所有部分的名称,它可以有数十万个名称。同样,我只需要一个可以按索引访问的列表。这些与树视图分开存储以提高效率,树视图仅在需要时检索它们。这需要一段时间来加载,并且对我的程序来说在内存方面非常昂贵。但我不必担心访问时间,因为一次只能访问几个。

希望这能让您了解我要完成的工作。

ps 我在 StackOverflow 上发布了很多关于优化 Delphi 的问题。我的程序读取 100,000 人的 25 MB 文件,并在 8 秒内为他们创建数据结构和报告和树形视图,但使用 175 MB 的 RAM。我正在努力减少这种情况,因为我的目标是在 32 位 Windows 中加载数百万人的文件。


我刚刚在这个 StackOverflow 问题中找到了一些优化 TList 的绝佳建议: 是否有更快的 TList 实现?

0 投票
7 回答
7460 浏览

delphi - 有什么方法可以让 TStringList.CommaText 不使用引号转义逗号?

我正在做一些代码生成工作,我需要做的一件事是创建一个函数调用,其中一个参数是函数调用,如下所示:

TStringList.CommaText 对于生成参数列表非常有用,但是当我遍历树来构建外部函数调用时,我最终得到的结果如下所示:

它引用了第三个参数,因为它包含逗号,并且产生了无效代码。但是我不能做一些简单的事情,比如 StringReplace all double quotes with empty strings,因为函数参数很可能是一个内部带有双引号的字符串。有没有办法让它不逃避包含逗号的行?

0 投票
3 回答
8583 浏览

delphi - 使用分隔符将字符串解析为 TStringList,似乎也解析空格(Delphi)

我有一个由某个字符分隔的简单字符串,比如说逗号。我应该能够创建一个 TStringList 并将其分隔符设置为逗号,然后将 DelimitedText 设置为我要解析的文本,并且应该自动解析它。

问题是当我查看输出时,它还包含空格作为分隔符并分割我的结果。我怎样才能避免这种情况,或者有更好的方法来做到这一点。

0 投票
4 回答
1035 浏览

delphi - Delphi TStringList 包装器实现动态压缩

我有一个用于在 TStringList 中存储许多字符串的应用程序。这些字符串将在很大程度上彼此相似,并且我突然想到可以即时压缩它们 - 即根据唯一文本片段加上对先前存储片段的引用来存储给定字符串。StringLists,例如完全限定的路径和文件名列表,应该能够被大大压缩。

有谁知道实现此功能的 TStringlist 后代 - 即提供对未压缩字符串的读写访问权限,但将它们存储在内部压缩,以便 TStringList.SaveToFile 生成压缩文件?

虽然您可以通过在每次访问之前解压缩整个字符串列表并在之后重新压缩它来实现这一点,但这会不必要地慢。我追求的是对增量操作和随机“搜索”和读取有效的东西。

TIA 罗斯

0 投票
2 回答
4707 浏览

delphi - 带有分隔符的字符串列表?

我在存储为字符串的对象中有一个名为 HistoryText 的属性。我想在网格中显示所有行。我应该能够删除和编辑网格中的行。格式为:

所以每一行都有 4 个字段,日期、时间、用户和消息,分隔符字符串为“-$-”。作为分隔符一个字符串而不是一个字符,它不能被分配给 stringlists delimiter 属性。

我有一个例程将字符串提取到 Stringlist:

它似乎工作正常。我的问题是将 StringList 中的更改同步回原始 String 属性?这个分隔符有很多历史数据,所以我不认为将其更改为 TChar 是一个现实的选择。

更新: 澄清。我想我可以设法使用上面的方法将 String 转换为 StringList 。然后在网格中显示它应该不会那么难。当我想将 TStringList 转换回原始的 String 属性时,问题就出现了,以 '-$-' 作为分隔符。例如,我不能做 HistoryText := myStringList.Delimitedtext。

第二次更新: 我已经解决了。你们都得到了 +1 的快速答案,并且真的很想提供帮助。总结一下我是怎么做到的。

从历史文本中读取:

现在每一行都有 3 个 '-$-' 分隔符,并且每行像往常一样由换行符分隔。

  • 在循环中解析 Stringlist 并将其显示在网格中。我不再关心 MyStringList 了。
  • 让用户删除和编辑网格中的行。
  • 完成后在网格中按行和列循环并构建一个与原始格式相同的新字符串。
  • 将该字符串分配给 HistoryText。

所以将焦点从 StringList 转移到网格上更容易:)

0 投票
5 回答
15199 浏览

delphi - 如何在 Delphi TStringList 中更快地搜索名称/值对?

我通过在运行时将所有字符串放在 TStringList 中来在应用程序中实现语言翻译:

然后我使用以下方法获得翻译:

无论如何,使用这种方法大约需要 30 微秒来定位记录,有没有更好的方法来实现相同的结果?

更新:为了将来参考,我在这里写了按照建议使用 TDictionary 的新实现(适用于 Delphi 2009 和更新版本)

新的 GetTranslation 函数的执行速度(在我的 2000 个样本记录上)比第一个版本快 1000 倍。

0 投票
1 回答
7666 浏览

delphi - 如何在自定义 delphi 组件中实现 stringlist 属性?

我正在创建我的第一个自定义 Delphi 组件。它基本上是一个自定义的 Tpanel,上面显示了标题和行文本。

我希望能够使用字符串列表添加多行文本。

测试组件时,添加行时无法在面板上显示文本行:NewLinesText.add('line1 text')

但是,当我在运行时创建并填充一个新的字符串列表然后将其分配给我的控件时,它确实有效: controlPanelitem.NewLinesText = MyNewStringlist

我希望能够添加这样的行:NewLinesText.add('line1 text')

我在 WinXP 上使用 Delphi 7 Professional。请参阅下面的代码。

任何帮助,将不胜感激!