【问题标题】:String comparion against a set of string values与一组字符串值的字符串比较
【发布时间】:2013-08-06 05:42:05
【问题描述】:

我有这样的函数(foo):我需要比较输入字符串并相应地执行任务。 任务是相同的,但仅适用于一组选定的值。对于所有其他值什么都不做。

function foo(string x)

{
if(x == "abc")
    //do Task1

if(x == "efg")
    //do Task1
if(x == "hij")
    //do Task1
if(x == "lmn")
    //do Task1
}

除此之外还有其他方法可以进行检查吗?还是将OR 运算符放在if 中?

首选的方式是什么?

【问题讨论】:

  • switch 语句非常适合这种情况;它允许您编写目标值,并很好地分离并使用最少的不必要的样板。
  • switch 语句在这里并没有太大的不同。
  • 有些人偏爱if (new[] {"abc", "efg", "hij", "lmn"}.Contains(x)) { Task1(); }...我不确定,但它有效。
  • @anaximander 好一个。但有趣的是string[] 实际上并没有包含方法Contains,所以这只是因为Linq。并不是说那是个问题。纯数组解决方案是if (Array.IndexOf(new[] {"abc", "efg", "hij", "lmn"}, x) != -1) { ... },但这看起来很糟糕。
  • 您只是在寻找一些不错的内联语法吗?如果是这样,您始终可以创建一个扩展方法,为您提供 if(x.Is("abc", "efg", "hij", "lmn")) { } 之类的语法

标签: c# .net string


【解决方案1】:

有很多方法可以做到这一点。一种是:

var target = new HashSet<string>{ "abc", "efg", "lmn" };
if (target.Contains(x)) {
    ...
}

[我的字符串列表] 最多可以增长到 50 个字符串,这是一种罕见的可能性。

那么你应该在你的班级中将target 设为static readonly,如下所示:

private static readonly StringTargets = new HashSet<string>{ "abc", "efg", "lmn" };

这样做将确保该集合只创建一次,并且不会在每次执行通过使用它的方法时重新创建。

【讨论】:

  • +1 我会说这是ifswitch 更好的替代品,switch 你仍然在编写相同数量的代码。
  • 同意,还取决于您放入其中的比较条目的数量,使用 List VS a hashset 可能会更快,但随着比较列表的增加,我认为 hashset 提供了更好的性能。在这里看到这篇文章。 stackoverflow.com/questions/150750/hashset-vs-list-performance
  • 我认为最好的一点是它可以让您轻松地将target 移动到某个类或提供程序中并执行if(BusinessRulesFooClass.Something(x))。事实上,根据情况,可能一直都是这样......
  • @NOOB 使用 10 个字符串时,您仍然应该获得大约三倍的速度提升。将其设为静态可确保每次代码通过该方法时都不会重新创建集合对象。将其设为只读是一种向代码读者表明您不打算在初始化后替换集合实例的方法。这可以在编译器中进行额外的优化。
  • @NOOB 你得到什么错误?与任何static 变量一样,它需要在方法之外定义,并且它的声明不能使用var。从您的方法之外的答案中复制粘贴第二个代码 sn-p ,它应该可以工作。我假设您的文件顶部也有using System.Collections.Generic;
【解决方案2】:

这样做

function foo(string x)
{
  switch(x)
  {
      case "abc":
      case "efg":
      case "hij":
      case "lmn":
        {
          //do task 1
          break;
        }
      default:
        break;
  }
}

您也可以这样做

if(x == "abc"||x == "efg"||x == "hij"||x == "lmn")
   //do Task1

【讨论】:

  • 我认为以这种方式实现 switch case 对我来说可能是一个更好的解决方案。
  • 这会导致对所有情况进行比较操作吗?而不是寻找第一次出现的任务。
【解决方案3】:

一种方法是创建一个可接受字符串的数组,然后查看该数组是否包含 x

function foo(string x)

{


     string[] strings = new string[] {"abc", "efg", "hij", "lmn"};

     if (strings.contains(x)){
        //do task 1
     }
}

【讨论】:

    【解决方案4】:

    您可以使用带有默认值的 switch 语句来捕获任何不匹配的内容

    http://blogs.msdn.com/b/brada/archive/2003/08/14/50227.aspx

    function foo(string x) {
    
        switch(x) {
    
         case "abc":
          //do task 1
         break;
    
         case "efg":
          //do task 2
         break;
    
         default:
          //all other cases
         break;
        }
    }
    

    【讨论】:

    • 他想执行相同的任务而不是不同的任务(所有任务都执行 Task1,而不是任务 1 在一个任务 1 和另一个任务 2)
    • 答案方向正确,但格式错误...可能误解了问题...
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-03-15
    • 2012-12-16
    • 2021-08-05
    • 1970-01-01
    相关资源
    最近更新 更多