greenorangesan
greenorangesan

Reputation: 17

Skipping a range of values in for loop C#

I'm trying to cycle through chars in a string.

string cycleMe = "Hi StackOverflow! Here is my string."

However, I want to skip over certain ranges of indexes. The ranges I want to skip over are stored in a List of objects, delims.

List<Delim> delims = delimCreator();

To retrieve each starting index and ending index for a range, I have to write a loop that accesses each "delim":

delims[0].getFirstIndex() //results in, say, index 2
delims[0].getLastIndex() //results in, say, index 4

delims[1].getFirstIndex() //results in, say, index 5
delims[1].getLastIndex() //results in, say, index 7

(there can be infinitely many "delim" objects in play)

If the above were my list, I'd want to print the string cycleMe, but skip all the chars between 2 and 4 (inclusive) and 5 and 7 (inclusive).

Expected output using the numbers above:

HiOverflow! Here is my string.

Here is the code I have written so far. It loops far more often than I'd expect (it loops ~x2 the number of characters in the string). Thanks in advance! =)

  List<Delim> delims = delimAggregateInator(displayTextRaw);

  for (int x = 0; x < cycleMe.Length;x++){

    for (int i = 0; i < delims.Count; i++){

      if (!(x >= delims[i].getFirstIndex() && x <= delims[i].getLastIndex())){


          Debug.Log("test");


      }
    }

Upvotes: 0

Views: 1157

Answers (3)

programses
programses

Reputation: 313

You should use LINQ for that

    struct Delim
    {
        public int First { get; set; }
        public int Last { get; set; }
    }

    static void Main(string[] args)
    {
        string cycleMe = "Hi StackOverflow! Here is my string.";

        var delimns = new List<Delim> { new Delim { First=2, Last=4}, new Delim { First = 5, Last = 7 } };

        var cut = cycleMe.Where((c, i) => 
           !delimns.Any(d => i >= d.First && i <= d.Last));

        Console.WriteLine(new string(cut.ToArray());
    }

That means I am basically only selecting letters, at positions which are not part of any cutting range.

Also: Fix your naming. A delimiter is a character, not a position (numeric)

Upvotes: 1

Just Shadow
Just Shadow

Reputation: 11881

Solution might be converting the string to char array, replacing the desired parts to spaces, and converting the output back to string.

Here is the modified version of your code:

string cycleMe = "Hi StackOverflow! Here is my string."
var charArray = cycleMe.ToCharArray(); // Converting to char array

List<Delim> delims = delimAggregateInator(displayTextRaw);
for (int x = 0; x < cycleMe.Length;x++){
  for (int i = 0; i < delims.Count; i++){
    // ORIGINAL: if (!(x >= delims[i].getFirstIndex() && x <= delims[i].getLastIndex())){
    if (x >= delims[i].getFirstIndex() && x <= delims[i].getLastIndex()){
       Debug.Log("test");
       charArray[x] = ' '; // Replacing the item with space
    }
}

string output = new string(charArray); // Converting back to string

P.S. This is probably not the most optimal solution but at least it should work.

Upvotes: 1

AJITH
AJITH

Reputation: 1175

I assume that by skipping you meant you want to omit those characters from the original string. If that is the case, you can try Aggregate extension method like below.

string result = delims.Aggregate<Delim, string>(cycleMe, (str, d) => cycleMe = cycleMe.Remove(d.FirstIndex, (d.LastIndex - d.FirstIndex) + 1));

Make sure that the delim list is in the proper order.

Upvotes: 3

Related Questions