【问题标题】:How do I check whether a string exists in an array?如何检查数组中是否存在字符串?
【发布时间】:2011-06-12 03:47:11
【问题描述】:

我有这个代码:

var
  ExtString: string;
const
  Extensions : array[0..4] of string = ('.rar', '.zip', '.doc', '.jpg', '.gif');

if ExtString in Extensions then

在最后一行,我得到一个错误:

[DCC 错误] E2015 运算符 ('then') 不适用于此操作数类型

我认为我无法做到这一点,那么我该如何正确执行我的任务?

【问题讨论】:

标签: arrays string delphi


【解决方案1】:

您可以使用System.StrUtils 中的函数IndexStr(区分大小写)或IndexText(不区分大小写)在数组中查找字符串并检索索引。

var
  ExtString: string;
const
  Extensions : array[0..4] of string = ('.rar', '.zip', '.doc', '.jpg', '.gif');
begin
  if (IndexStr(ExtString, Extensions) <> -1) then
    ShowMessage('Finded')
  else
    ShowMessage('Not finded');

Link to help in docwiki from embarcadero.

【讨论】:

    【解决方案2】:

    正如您所发现的,您无法使用 in 检查字符串数组中的字符串。

    您可以使用此函数代替if 语句。

    function StrInArray(const Value : String;const ArrayOfString : Array of String) : Boolean;
    var
     Loop : String;
    begin
      for Loop in ArrayOfString do
      begin
        if Value = Loop then
        begin
           Exit(true);
        end;
      end;
      result := false;
    end;
    

    你可以这样称呼它。

    if StrInArray(ExtString,Extensions) then

    StrUtils.pas 已经定义了这个。

    function MatchStr(const AText: string; const AValues: array of string): Boolean; 
    

    【讨论】:

    • +1 表示 MatchStr,但不幸的是它被命名了。它应该是名词而不是动词。我必须说我不喜欢新的退出语法。但是如果你要使用它,你不应该一直使用它。在同一个例程中使用 result 和 exit() 会使解析变得更加困难。
    • 注意区分大小写。文件系统不区分大小写,您可以找到大量带有 .JPG 扩展名的文件。上面的代码会错过这个。
    • @Misha:这就是MatchText 的用途。在某些 Delphi 版本中,它仅以 AnsiMatchText 的形式存在(并且可能在 WideStrings.pas 中以 WideMatchText 的形式存在。
    【解决方案3】:

    从常量数组​​初始化一个 TStringList 实例并使用 IndexOf()。

    【讨论】:

    • 太重量级了,简单的循环更好
    • 如果频繁执行并且 TStringList 是持久的,则不会。谁知道这还能用来做什么?
    • 使字符串列表持久化并放弃线程安全。即使这样,您也必须分配给毫无意义的字符串列表。毫无疑问,循环更好。字符串列表是破解螺母的大锤。
    • 只有 4 个字符串可能是矫枉过正。但是,线程安全不是问题,因为字符串列表可以初始化一次,然后它是只读的。
    • TStringList.IndexOf 不是重量级的。一个简单的 for 循环也不是更好。
    【解决方案4】:

    有时最简单的解决方案并不是最明显的

    var
      ExtString: string;
    const
      Extensions = ('.rar,.zip,.doc,.jpg,.gif');
    
    if Pos(ExtString, Extensions) > 0 then
    

    或者在我喜欢的新 StrUtils 库中使用 .Netrification!想想帮手!

    if Extensions.IndexOf(ExtString) > -1 then
    

    或者您可以使用 .Split(',') 循环遍历数组

    【讨论】:

    • 一个明显的缺点是,这将匹配例如.do.d 或仅匹配. 以及.doc
    • 人们总是可以通过检查字符串长度来锁定项目,并且只需滚动'.';所以用户只会传入扩展名。简而言之,这将有利于功能的防弹。
    • @JosephPoirier:不,没有办法使这种方法防弹。扩展名不必是三个字符长(.html.7z、...)。如果字符串包含html,您可能会错误地将tm 视为扩展名。不幸的是,这种方法存在根本缺陷。只需使用 Robert Love 建议的标准数组方法即可。
    • 我不同意。
    • @JosephPoirier:为什么?当然,计算机程序的正确性是最重要的吗?如果您的任务是设计一个返回 True 的函数,当且仅当一个字符串在给定的一组选项(如 html7zdocx)中,并且您的函数 also i> 为其他字符串返回True(如tml, 7cx),那肯定不行吗?如果您删除罗伯特答案中多余的beginend,这是一个四行解决方案,不仅更快(CPU 时间),而且显然是正确的,并且始终给出正确的答案。这也是一个标准和惯用的解决方案。
    猜你喜欢
    • 2022-12-18
    • 1970-01-01
    • 2021-12-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多