2011-01-12 226 views
4

我想检查一个字符串是否以列表中的任何字符开头。我目前在C#中的实现如下:检查一个字符串是否以列表中的任何字符开头

char[] columnChars = new char[] { 'A', 'B', 'C', 'D', 'E' }; 
private bool startWithColumn(string toCheck) 
{ 
    for(int i=0; i<columnChars.Length; i++) 
    if (toCheck.StartsWith(columnChars[i]+"")) 
    { 
     return true; 
    } 

    return false; 
} 

我想知道是否有解决方案比较好?

+0

众多的答案去证明有*绝对*很多方法可以做到在C#同样的事情。 – JYelton

回答

7

打开检查周围,看看第一个字符是否在允许的集合中。

char[] columnChars = new char[] { 'A', 'B', 'C', 'D', 'E' }; 
private bool startWithColumn(string toCheck) 
{ 
    return toCheck != null 
       && toCheck.Length > 0 
       && columnChars.Any(c => c == toCheck[0]); 
} 
4

你可以得到的第一个字符一个字符串容易够:

char c = toCheck[0]; 

然后检查它是否是数组中:

return columnChars.Contains(c); 
0

我相信这一个会更快:

char[] columnChars = new char[] { 'A', 'B', 'C', 'D', 'E' }; 
private bool startWithColumn(string toCheck) 
{ 
    for(int i=0; i<columnChars.Length; i++) 
    if (toCheck.Length > 0 && toCheck[0] == columnChars[i])) 
    { 
     return true; 
    } 

    return false; 
} 
1
return Regex.IsMatch(toCheck, "^[A-E]"); 

或者:

return toCheck.Length > 0 && columnChars.Contains(toCheck[0]); 
+1

可怜的正则表达式。经常矫枉过正,往往不够强大:( – delnan

0
private bool startWithColumn(string toCheck) 
{ 
    return (columnChars.IndexOf(toCheck[0]) >=0); 
} 
0

最显而易见的方法是线性搜索在数组中的字符串的第一个字符:

private bool startWithColumn(string toCheck) 
{ 
    return !string.IsNullOrEmpty(toCheck) 
      && Array.IndexOf(columnChars, toCheck[0]) != -1; 
} 

如果您正在寻找表现,考虑使用HashSet<char>或类似的数组而不是数组,它应该给你一个恒定的时间查找。如果阵列更大,这可能是唯一值得的;你必须测量这种或那种方式。

0

这里是我想出了:

readonly char[] columnChars = new char[] { 'A', 'B', 'C', 'D', 'E' }; 
    private bool startWithColumn(string toCheck) 
    { 
     return columnChars.Contains(toCheck.Substring(0, 1).ToCharArray()[0]); 
    } 

编辑

没看到制作转换次数减少的可能性:

3
return columnChars.Any(x => x == toCheck[0]); 
0

你可以做它使用Contains和ElementAt:

char[] columnChars = new char[] { 'A', 'B', 'C', 'D', 'E' }; 
String testString = "This is test String"; 
var exists = columnChars.Contains(testString.ElementAt(0)); 
2

如果你的角色“列表”肯定会是一个char[],我会假设你最好搭配:

return toCheck.IndexOfAny(columnChars) == 0; 

免责声明:我没有这个基准。但那种方法就是坐在那里。

0

我爱我的LINQ所以在这里:

 string str = "A quick brown fox"; 
     char[] chars = { 'A', 'B', 'C', 'D', 'E', 'F' }; 

     var query = from c in str.Substring(0, 1) 
        join c1 in chars on c equals c1 
        select c; 

这会给你所有的字符,在列表中匹配字符串的第一个字符。稍作修改,你甚至可以得到你正在搜索的字符列表中的字符索引,在这种情况下索引为0。

这里是代码:

 string str = "A quick brown fox"; 
     char[] chars = { 'Z', 'X', 'A', 'B', 'C', 'D', 'E', 'F' }; 

     var query = from c in str.Substring(0, 1) 
        join c1 in chars on c equals c1 
        select new { Character = c, Index = chars.ToList().IndexOf(c) }; 

     var found = query.ToArray(); 
+0

所以,你需要一点点(很少?)修改来解决OP的问题,最后你会得到一个可怕的解决方案?抱歉,但LINQ不是正则表达式是:P –

+0

@Martinho啊,另外一个linq hater。正则表达式,认真吗?这样更容易维护,更具可读性吗?我猜你是代码为一个人的团队。 – SRM

+0

@Martinho这是对象linq,而不是linq sql,所以连接并不是那么昂贵,而且,从2005年开始,SQL服务器已经优化了所有的执行路径,所以ad hoc sql,比如linq生成,运行速度与存储过程一样快,因此参数不在窗口中。虽然我会承认我在linq查询中使用的chars.ToList可以被优化,但我不确定linq编译器是否会优化它并缓存该值,或者如果它被调用每次传递。创建一个本地va会更好riable并使用它来代替。 – SRM

4

我需要类似的东西,但对于字符串:

我想知道如果我的字符串subject开始与这些字符串:

var qualent3s = new string[] { "D", "M", "H", "JUK"}; 

LINQ这么做很简单:

qualent3s.Any(x => subject.StartsWith(x)) 
+0

您可以简化查询:'qualent3s.Any(subject.StartsWith)' –

0

在这种情况下,我使用的扩展方法是这样的:

public static bool StartsWithAny(this string Text, IEnumerable<string> Needles) { 
      return Needles.Any(x => Text.StartsWith(x)); 
     } 
相关问题