【问题标题】:Assign variable and check it within an IF evaluation分配变量并在 IF 评估中检查它
【发布时间】:2021-07-19 17:03:35
【问题描述】:

我怀疑这是否可行,但我还是会问,因为它会使我的代码更具可读性。

我必须为各种子字符串控制一个大字符串,并根据找到的子字符串以不同的方式对其进行详细说明。

目前我有一个嵌套的 if like

position = mystring.IndexOf("my substring")
if (position>0)
{
    position = mystring.IndexOf("somestring", position);
    [...]
}
else
{
    position = mystring.IndexOf("my substring2")
    if (position>0)
    {
        position = mystring.IndexOf("somestring2", position);
        [...]
    }
    else {...}
}

我能想到的唯一其他方法是双重转换 IndexOf 函数:

if (mystring.IndexOf("my substring")>0)
{

    position = mystring.IndexOf("somestring", mystring.IndexOf("my substring"));
    [...]
}
else if (mystring.IndexOf(mysubstring2)>0)
{
    position = mystring.IndexOf("somestring2", mystring.IndexOf("my substring2"));
    [...]
}
else {...}

有没有办法检查IndexOf() 结果并将其分配给if() 语句中的变量?

某事就行了

if ((position = mystring.IndexOf("my substring")) AndAlso position > 0) { ... }

或者有什么提示可以更好地处理这样一段代码?

【问题讨论】:

  • if ((position = mystring.IndexOf("my substring")) >= 0) {...}
  • 你使用if (position>0)但也许你应该使用if (position>=0),否则你排除了搜索字符串在开头的情况。
  • 虽然我怀疑这些是占位符,但请注意,如果找不到“my substring”,那么也不会找到“my substring2”。
  • @TimSchmelter 谢谢,我这样做是因为我知道它永远不会是第一个字符。
  • @Default 是的,只是占位符

标签: c# if-statement variable-assignment


【解决方案1】:

从技术上讲,你可以把它写成

int position;

if ((position = mystring.IndexOf("my substring")) > 0)
{

    // Note, that you should use position + "my substring".Length if 
    // "somestring" can't be part of previous match
    position = mystring.IndexOf("somestring", position);
    [...]
}
else if ((position = mystring.IndexOf(mysubstring2)) > 0)
{
    position = mystring.IndexOf("somestring2", position);
    [...]
}
else {...}

不过,我建议提取一个方法

private static bool FindMany(string source, out int lastIndex, params string[] toFind) {
  if (null == toFind)
    throw new ArgumentNullException(nameof(toFind));

  lastIndex = -1;
  int result = -1;

  if (string.IsNullOrEmpty(source))
    return false;

  int index = 0;

  for (int i = 0; i < toFind.Length; ++i) {
    result = source.IndexOf(toFind[i], index);

    index += toFind[i].Length;

    if (index < 0)
      return false;          
  }

  lastIndex = result;

  return true;
}

你可以用作什么

int position;

if (FindMany(mystring, out position, "my substring", "somestring") {
  // "my substring" found

  if (position >= 0) {
    // "somestring" is found as well; its index - position   
    ...
  }
  else {
    // only "my substring" has been found
  }
}
else if (FindMany(mystring, out position, "my substring2", "somestring2") {
  // "my substring2" found

  if (position >= 0) {
    // "somestring2" is found  
    ...
  }
}

【讨论】:

  • 我很困惑。在像position = mystring.IndexOf("my substring") &gt; 0 这样的语句中,我希望position 被赋予后一个逻辑运算符的布尔值,而不是首先被分配一个值并随后进行测试。我试试看,谢谢。
  • 嗯,我怀疑我收到“无法将类型 'bool' 隐式转换为类型 'int'”错误
  • 只是缺少括号,这就是它不起作用的原因。
【解决方案2】:

这听起来确实像是正则表达式的一项工作,具有积极的后视能力: 积极的向后看确保(?&lt;=) 中的字符串先于另一个字符串存在

与带有 out 参数的 TryGet..approach 一起,它几乎可以成为一个单行。

但是,Dmitrys solution 是一个更面向未来的证明,因为它接受多个输入字符串进行搜索。构建正则表达式可能被证明是不可维护的

https://dotnetfiddle.net/D5WFyx

using System;
using System.Text.RegularExpressions;

public static void Main()
{
    string input = "here is my substring and then somestring";

    int position;
    if (TryGetIndex(input, "(?<=my substring.*)somestring", out position)){
        Console.WriteLine($"somestring index: {position}");
    }
    else if (TryGetIndex(input, "(?<=other substring.*)otherstring", out position)) {
        Console.WriteLine($"otherstring index: {position}");
    }

    bool TryGetIndex(string input, string pattern, out int position){
        var match = Regex.Match(input, pattern);
        if (match.Success){
            position = match.Index;
            return true;
        }
        position = -1;
        return false;
    }
}

【讨论】:

    【解决方案3】:

    是的,你可以这样做,就像这样:

    var myString = "Hello World";
    int pos;
    
    if ((pos = myString.IndexOf("World")) >= 0)
    {
        Console.WriteLine(pos); // prints 6
    }
    else if ((pos = myString.IndexOf("Some Other Substring")) >= 0)
    {
        // Do whatever
    }
    

    请注意,我使用myString.IndexOf(...) &gt;= 0,因为子字符串的索引可能是 0(即从第一个字符开始),如果没有找到,IndexOf 方法返回 -1

    但你更愿意像这样使用string.Contains

    var myString = "Hello World";
    
    if (myString.Contains("World"))
    {
        // Do whatever
    }
    else if (myString.Contains("Some Other Substring"))
    {
        // Do whatever
    }
    

    如果您不明确需要子字符串的位置,这会更好,但如果需要,请使用第一个

    【讨论】:

    • 谢谢,以前有人建议过这个解决方案,但它缺少括号,导致错误。
    • @des 是的,有人就是我,是的,起初我缺少括号,但罗德里戈·罗德里格斯编辑了答案以纠正我的错误
    【解决方案4】:

    使用Contains(),此外,如果您出于某种原因确实需要获得职位,请单独使用IndexOf()if (mystring.Contains("my substring")) { ... }

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2022-08-08
      • 1970-01-01
      • 2020-02-06
      • 1970-01-01
      • 2021-06-29
      相关资源
      最近更新 更多