简体   繁体   中英

How to decrement the index of a line in an array of strings?

I am making a code that decrements the line index in an array of strings. My array is like this:

1.ExampleFirst\n
  SomeText\n
  SomeOtherText\n
  FinalLine\n\n

2.ExampleSecond\n
  SomeText\n
  SomeOtherText\n
  FinalLine\n\n

and so on. The lengths of the lines are not the same. I want the text to be like this:

0.ExampleFirst\n
  SomeText\n
  SomeOtherText\n
  FinalLine\n\n

1.ExampleSecond\n
  SomeText\n
  SomeOtherText\n
  FinalLine\n\n

I have made this code:

int s = 0;

 while(s < lineCounter.Count())
   {
 if (int.TryParse(lineCounter[s].Substring(0, 1), out v) == true && lineCounter[s] != "\n") 
    {
      int m = int.Parse(lineCounter[s].Substring(0,1));
      lineCounter[s].Remove(0, lineCounter[s].IndexOf(".")).Insert(0, (m - 1).ToString());
      Console.WriteLine(lineCounter[s]);
     }
 else
       Console.WriteLine(lineCounter[s]);
       s++;

The "if" is executed only when the line contains the number and when the line is not a new line. The else is executed to write the other lines in the array.(I'm using console.writeLine to see the results. I know I have to change that part) When I execute this code, I get the following exception in the "if" statement:

An unhandled exception of type 'System.ArgumentOutOfRangeException' occurred in mscorlib.dll

Additional information: Index and length must refer to a location within the string.

To me this means that "if" is executed even when the new line between the last line of the first text block and the first line of the second text block is encountered. I can't explain why. Help please!

Declaring dotIndex with combination of string.Remove() and string.Insert() may do the trick.

string[] lineCounter = new string[]{
    "1.ExampleFirst\n",
    "  SomeText\n",
    "  SomeOtherText\n",
    "  FinalLine\n\n",
    "2.ExampleSecond\n",
    "  SomeText\n",
    "  SomeOtherText\n",
    "  FinalLine\n\n"
};

for (int i = 0; i < lineCounter.Count(); ++i) {
    int dotIndex = lineCounter[i].IndexOf('.');
    if (dotIndex < 1) //must be at least in the position of 2 or above
        continue;       
    int lineIndex = 0;
    if (int.TryParse(lineCounter[i].Substring(0, dotIndex), out lineIndex)) { //if can be parsed
        lineIndex--; //decrement lineIndex
        lineCounter[i] = lineIndex.ToString() + lineCounter[i].Remove(0, dotIndex);
    }
}

I prefer to use for-loop to make the loop more definite, but you could change that to while / do .

This works fine in my PC. Output:

在此处输入图片说明

Edit:

All the results should be in the lineCounter. If you want to see them along the function, you could do:

for (int i = 0; i < lineCounter.Count(); ++i) {
    int dotIndex = lineCounter[i].IndexOf('.');
    if (dotIndex < 1) { //must be at least in the position of 2 or above
        //Print here
        continue;       
    }
    int lineIndex = 0;
    if (int.TryParse(lineCounter[i].Substring(0, dotIndex), out lineIndex)) { //if can be parsed
        lineIndex--; //decrement lineIndex
        lineCounter[i] = lineIndex.ToString() + lineCounter[i].Remove(0, dotIndex);
    }
    //Print here also
}

you probably want this:

string[] lineCounter=new string[]{
"1.ExampleFirst\n",
"  SomeText\n",
"  SomeOtherText\n",
"  FinalLine\n",
"\n",
"2.ExampleSecond\n",
"  SomeText\n",
"  SomeOtherText\n",
"  FinalLine\n",
"\n"
};
int v = 0;
int s = 0;

while (s < lineCounter.Count())
{
    if (int.TryParse(lineCounter[s].Substring(0, 1), out v) == true && lineCounter[s] != "\n")
    {
        int m = int.Parse(lineCounter[s].Substring(0, 1));
        Console.WriteLine(lineCounter[s].Remove(0, lineCounter[s].IndexOf(".")).Insert(0, (m - 1).ToString()));
    }
    else
        Console.WriteLine(lineCounter[s]);
    s++;
}

I believe you may be having issues with empty lines on the string array. Maybe something like this works for you.

IEnumerable<string> ShiftIndexes(IEnumerable<string> lines) {
    foreach (string line in lines) {
        if (!string.IsNullOrEmpty(line) && char.IsDigit(line, 0)) {
            int dotPos = line.IndexOf('.');
            int index = int.Parse(line.SubString(0, dotPos));
            yield return (index - 1).ToString() + line.SubString(dotPos);
        }
        else
            yield return line;
    }
}

And then use it like this:

string[] shiftedLines = ShiftIndexes(originalLines).ToArray();

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM