Android Code Snippet [B4X] Index of Nth occurrence

Returns the index of the Nth occurrence of the string searched for.
Returns -1 if not found.
B4X:
Sub IndexOfNth(s As String, SearchFor As String, Count As Int) As Int
   Dim res As Int = -1
   For i = 0 To Count - 1
     res = s.IndexOf2(SearchFor, res + 1)
     If res = -1 Then Return -1
   Next
   Return res
End Sub

Example:
B4X:
Log(IndexOfNth("a,bcd,ef,gh", ",", 1)) '1
Log(IndexOfNth("a,bcd,ef,gh", ",", 2)) '5
Log(IndexOfNth("a,bcd,ef,gh", ",", 3)) '8
Log(IndexOfNth("a,bcd,ef,gh", ",", 4)) '-1
 

Erel

B4X founder
Staff member
Licensed User
Longtime User
Multiple exit points can be problematic in some cases. Mainly in large subs that do several things.
There are also cases where it is simpler to return early compared to continuing the flow with an invalid value or some edge case.

I don't think that it is problematic here as this is a very short and simple sub.
 

wonder

Expert
Licensed User
Longtime User
Edit: Fixed in Post #8.

B4X:
'Returns the index corresponding the nth ocurrence of the specified query in the given data
Sub IndexOfNth(occur As Int, query As String, data As String) As Int
    Dim index As Int
    Do While index > -1 And occur > 0
        index = data.IndexOf2(query, index + 1)
        occur = occur - 1
    Loop
    Return index
End Sub

No IF statements were harmed in the making of this function. :D
 
Last edited:

Mahares

Expert
Licensed User
Longtime User
No IF statements were harmed in the making of this function. :D

Your code works well too. To quickly compare it to Erel's, I simply renamed the variables and changed the order to match that of Erel's as shown below:
B4X:
Sub IndexOfNth(s As String, SearchFor As String, Count As Int) As Int
    Dim res  As Int
    Do While res  > -1 And Count  > 0
        res  = s.IndexOf2(SearchFor , res  + 1)
        Count  = Count  - 1
    Loop
    Return res
End Sub
 

Peter Meares

Member
Licensed User
Longtime User
This last one does not work if the first the SearchFor is at the start 0 because res+1 is = 1.
Erel's version works fine.
 

wonder

Expert
Licensed User
Longtime User
This last one does not work if the first the SearchFor is at the start 0 because res+1 is = 1.
Erel's version works fine.

B4X:
'Returns the index corresponding the nth ocurrence of the specified query in the given data
Sub IndexOfNth(occur As Int, query As String, data As String) As Int
    Dim index = data.IndexOf(query) As Int
    Do While index > -1 And occur > 1
        index = data.IndexOf2(query, index + 1)
        occur = occur - 1
    Loop
    Return index
End Sub

Fixed! :)
 
Top