Today I was looking for a fast way to find the index of a nth occurrence of a string in a string, so I found this very simple and intuitive site on which you can find and share .net extension methods, the website is http://www.extensionmethod.net Dah!
I couldn’t find what I looked for, so I shared my solution here; the website made it crazy easy to share this! Something I definitely would add to my log on how to create wonderful websites, simple and effective.
Salam Dear, imad hope this helps, it is not safe though OutOfRangeException may occure as you know.
string str = “Hi imad how are you imad, how is your family imad, thanks for your time imad”;
public static int StringIndex(this string str, int stringIndex)
{
string[] strArray = str.Split(‘ ‘);
string find = “imad”;
var occInPlace = strArray.Select((occ, index) => new { Occ = occ, occInd = index });
var strOcc = from occure in occInPlace where occure.Occ.Replace(“,”, “”) == find select occure.occInd;
return strOcc.ToArray()[stringIndex]; ;
}
this is a better version with ReplaceAny extension but i believe it can be optimized somehow
public static int StringIndex(this String str, string toFind, int occurenceNumber, char[] replaceCharArray, char replaceToChar)
{
string[] strArray = str.ToLower().ReplaceAny(replaceCharArray, replaceToChar).Split(‘ ‘);
var occInPlace = strArray.Select((occ, index) => new { Occ = occ , occInd = index });
var strOcc = from occure in occInPlace where occure.Occ == toFind.ToLower() select occure.occInd;
int[] occurences = strOcc.ToArray();
return occurences.Length >= occurenceNumber ? occurences[occurenceNumber-1] : -1;
}
public static string ReplaceAny(this string str, char[] replaceCharArray, char replaceToChar)
{
foreach (char chr in replaceCharArray)
str = str.Replace(chr, replaceToChar);
return str;
}
hello Emad,
yes am following up on you even here :)….
dear i checked the above code you worte, and also the other two comments above, i noticed that your code is more “general”, coz what if you were looking for “hi emad” not only “emad” ! i dont think the code in the two commments above will do the job, yet your original code will do,
i just have some modifications on your code -Suggested of course :); where i saved you a variable and an if statment….please feel free to share your feelings 🙂
public static int IndexOfOccurence(this string str, string stringToBeFound, int occurrence)
{
occurrence +=1;
int indexOfPassedString = 0 – stringToBeFound.Length;
do
{
indexOfPassedString = str.IndexOf(stringToBeFound, indexOfPassedString + stringToBeFound.Length);
occurrenceCounter–;
}
while (occurrence != 0 || indexOfPassedString == -1);
return indexOfPassedString;
}
sorry emad, couldnt stop, but i beleive this is more optimized solution 🙂
Public Shared Function FindNthOcc(ByVal StrtoSearch As String, ByVal StrtoFind As String, ByVal TargetOcc As Integer) As Integer
Dim Str As String() = Regex.Split(StrtoSearch, StrtoFind, RegexOptions.IgnoreCase Or RegexOptions.Multiline)
If Str.Length = 0 OrElse Str.Length <= TargetOcc Then
Return -1
Else
Return StrtoSearch.IndexOf(StrtoFind & Str(TargetOcc))
End If
End Function
since there is a bug in me last post, especially if the text contains “repetitive words”..here is the last on 🙂
Public Shared Function FindNthOcc(ByVal StrtoSearch As String, ByVal StrtoFind As String, ByVal TargetOcc As Integer) As Integer
Dim Str As String() = Regex.Split(StrtoSearch, StrtoFind, RegexOptions.IgnoreCase Or RegexOptions.Multiline)
If Str.Length = 0 OrElse Str.Length <= TargetOcc Then
Return -1
Else
Array.Resize(Str, TargetOcc)
Return String.Join(StrtoFind, Str).Length
End If
End Function
Salam Ali,
Thanks for your reply, very interesting way indeed! Though I believe Yousef had a valid point there. Please keep your comments coming, that’s the best part of coding; discussions 🙂
LoL Yousef! (Yousef is my Project Manager people!)
If I knew that you follow my blog I would have worked on getting a raise with special posts 😉 hehe
As for this solution, I like it…though probably a stress testing should show which solution might have better performance, I haven’t tried your code in the first place so maybe the next commentator can say his word on this 😉
Btw people, on the trails of this issue Yousef provided a very simple solution for another problem that made me go Dah! if you needed this nth occurrence method, think about using Split() and the index of the array 😉
hello dears,
thanks Emad, we will see about the raise issue :),
i have checked the performance and it turned out that for the first run, your code is faster, while in the consequent execution your code is Slightly faster,
i have modified my code as below, and it matches your code speed, but its more readable 🙂
Public Shared Function FindNthOcc(ByVal StrtoSearch As String, ByVal StrtoFind As String, ByVal TargetOcc As Integer) As Integer
Dim Str As String() = StrtoSearch.ToLower.Split(New String() {StrtoFind.ToLower}, StringSplitOptions.None)
If Str.Length = 0 OrElse Str.Length <= TargetOcc Then
Return -1
Else
Array.Resize(Str, TargetOcc)
Return String.Join(StrtoFind, Str).Length
End If
End Function