I\'m trying to make a function that returns the index of the Nth occurrence of a given char in a string.
Here is my attempt:
private int IndexOfNth(s
First of all, I'd make it an extension method. This way, you can skip the otherwise obligatory null
check and also just call it on a string like you would do with IndexOf
, IndexOfAny
etc.
Then I'd make two methods of this. One to retrieve all indexes (IndexesOf
, that might come handy at sometime) and the other one (IndexOfNth
) uses the first function to check for the nth index:
using System;
using System.Collections.Generic; // # Necessary for IList
using System.Linq; // # Necessary for IList.ToArray()
///
/// Returns all indexes of the specified in the current string.
///
/// The current string this method is operating on.
/// The value to be searched.
/// Null , if is null or empty.
/// An array holding all indexes of in this string,
/// else.
static int[] IndexesOf(this string @this, string value)
{
// # Can't search for null or string.Empty, you can return what
// suits you best
if (string.IsNullOrEmpty(value))
return null;
// # Using a list instead of an array saves us statements to resize the
// array by ourselves
IList indexes = new List();
int startIndex = 0;
while (startIndex < @this.Length)
{
startIndex = @this.IndexOf(value, startIndex);
if (startIndex >= 0)
{
// # Add the found index to the result and increment it by length of value
// afterwards to keep searching AFTER the current position
indexes.Add(startIndex);
startIndex += value.Length;
}
else
{
// # Exit loop, if value does not occur in the remaining string
break;
}
}
// # Return an array to conform with other string operations.
return indexes.ToArray();
}
///
/// Returns the indexes of the th occurrence of the specified
/// in the current string.
///
/// The current string this method is operating on.
/// The value to be searched.
/// The 1-based nth occurrence.
/// -1 , if is null or empty -or-
/// is less than 1.
static int IndexOfNth(this string @this, string value, int n /* n is 1-based */)
{
// # You could throw an ArgumentException as well, if n is less than 1
if (string.IsNullOrEmpty(value) || n < 1)
return -1;
int[] indexes = @this.IndexesOf(value);
// # If there are n or more occurrences of 'value' in '@this'
// return the nth index.
if (indexes != null && indexes.Length >= n)
{
return indexes[n - 1];
}
return -1;
}
You can overload these using char value
instead of string value
in the signature and calling their respective counterparts passing value.ToString()
. Et voilá!
Surely, these methods can be refactored, e.g. using LINQ, make IndexesOf
recursive etc.