C# - 将字符串中特定字符的索引添加到整数列表中

时间:2017-02-22 23:14:34

标签: c# .net

寻找有关如何获取以下代码的指导,以生成longString中每个空格和连字符的索引列表。

每当我运行下面的语句时,它只会在我的整数列表中添加5。鉴于我在下面使用的字符串作为示例,我试图让它收集5,11,14,24和27。

static void Main(string[] args)
    {
        string longString = "hello world my user-name is stevieray8450";
        int longStringLength = longString.Length;
        char whiteSpace = ' ';
        char hyphen = '-';

        // list to store all indexes of white space
        List<int> specialIndexes = new List<int>();

        foreach (char c in longString)
        {
            if (c.Equals(whiteSpace) || c.Equals(hyphen))
            {
                specialIndexes.Add(longString.IndexOf(c));
            }
        }

为了我c循环中的foreach字符为什么我的{{1>}每次在我{{{>>中评估为

1}}陈述。

任何想法,意见,评论欢迎:)谢谢!

8 个答案:

答案 0 :(得分:1)

longString.IndexOf(c)c = ' '总是评估为5. IndexOf时,只返回其参数第一次出现的索引。

  

public int IndexOf(char value)

     

如果找到该字符,则从零开始的索引值位置,如果不是,则返回-1。

请记住,char是value-type,因此默认情况下您正在使用副本。

答案 1 :(得分:0)

当您调用index of时,您将获得字符串

中第一个匹配项的索引
  

https://msdn.microsoft.com/en-us/library/k8b1470s(v=vs.110).aspx

你可以试试:

string longString = "hello world my user-name is stevieray8450";
int longStringLength = longString.Length;
char whiteSpace = ' ';
char hyphen = '-';
int index = 0;

// list to store all indexes of white space
List<int> specialIndexes = new List<int>();

foreach (char c in longString)
{
    if (c.Equals(whiteSpace) || c.Equals(hyphen))
    {
        specialIndexes.Add(index);
    }
    index++;
}

答案 2 :(得分:0)

以下一行......

specialIndexes.Add(longString.IndexOf(c));

...将返回c的第一次出现的索引,而不是当前的索引。在示例字符串中,第一个空格或连字符是位置5处的空格。

解决此问题的最佳方法是使用for循环,并将计数器值存储为索引。

答案 3 :(得分:0)

这是因为char类型是值类型,并且IndexOf仅返回第一次出现的索引。也就是说,它将返回5作为结果。

您需要将自己的计数器添加到foreach循环或循环for并在其中使用其索引。

答案 4 :(得分:0)

static void Main(string[] args) {
    string longString = "hello world my user-name is stevieray8450";
    HashSet<char> desiredChars = new HashSet<char> { ' ', '-' };

    List<int> specialIndexes = longString
       .Select((char, i) => new KeyValuePair<char, int>(char, i))
       .Where(kvp => desiredChars.Contains(kvp.Key))
       .Select(kvp => kvp.Value)
       .ToList();
}

答案 5 :(得分:0)

以下是您的代码的另一个版本:

string longString = "hello world my user-name is stevieray8450";
int longStringLength = longString.Length;
char whiteSpace = ' ';
char hyphen = '-';

// list to store all indexes of white space
List<int> specialIndexes = new List<int>();

int index = 0;
do
{
       index = longString.IndexOf(whiteSpace, index);
       if (index > -1)
       {
             specialIndexes.Add(index);
             index++;
       }

} while (index != -1);

答案 6 :(得分:0)

我更喜欢LINQ解决方案,我可以使用它们。 LINQ的问题是索引不会转发到下一个语句。要了解我的意思,请考虑以下事项:

var longString = "hello world my user-name is stevieray8450";

var badIndices = longString
    .Where(c => c == ' ')
    .Select((c, i) => i)
    .ToArray();

Console.WriteLine($"[bad!] found ' ' at indices: {string.Join(", ", badIndices)}");

虽然的结果似乎应为5, 11, 14, 24, 27,但实际结果如下:

  

[bad!]发现&#39; &#39;在指数:0,1,2,3,4

为了继承正确的索引,我们必须动态创建中间版anonymous type

    var indices = longString
        .Select((c, i) => new
        {
            idx = i,
            val = c
        })
        .Where(ci => ci.val == ' ')
        .Select(ci => ci.idx)
        .ToArray();

    Console.WriteLine($"[good] found ' ' at indices: {string.Join(", ", indices)}");

一旦你习惯它并没有那么糟糕,我更喜欢写自己的循环。结果是:

  

[good]发现&#39; &#39;在指数:5,11,14,24,27

但是,在这种特殊情况下,for-loop效率更高,并且在LINQ的大约1/5时间内完成。

答案 7 :(得分:0)

this answer开始,您可以将for循环与IndexOf的(char,int)重载结合使用,以形成简洁的解决方案:

var specialIndexes = new List<int>();
for (int i = s.IndexOf(' '); i > -1; i = s.IndexOf(' ', i + 1))
{
    specialIndexes.Add(i);
}