Android Question Return location of string in a delimited string

JamesGreaves

Active Member
Licensed User
Is there a command which searched a "delimitered" string and returns the position of another string?

NameList = "Jack, John, Peter, Mary, Sue"
FindMe = "Mary"
Delimiter = ","
Pos = Find_Position(NameList, FindMe , Delimiter )

It should return 4.
 

DonManfred

Expert
Licensed User
Longtime User
No.

You need to write a small sub which does what you want.
Split the string, iterate through the array and find the correct index to return from that sub.
 
Upvote 0

JamesGreaves

Active Member
Licensed User
Ok, I have done code for what i wanted, just sharing :)

B4X:
Sub Find_Position (ThisData As String, Find_This As String, Delimiter As String, CaseSensitive As Boolean) As Int
 
    If CaseSensitive=False Then
        ThisData=ThisData.ToUpperCase
        Find_This=Find_This.ToUpperCase
    End If
 
    Dim ThisRow() As String = Regex.Split(Delimiter, ThisData)
    
    Dim NotFound As Boolean = False
    Dim RowCount As Int = 0
    Do While RowCount < ThisRow.Length And NotFound = False
        If Find_This = ThisRow(RowCount).Trim Then NotFound = True
        RowCount = RowCount + 1
    Loop
    
    Return RowCount
    
End Sub

And you use it like this:

B4X:
Dim NameList As String = "Jack, John, Peter, Mary, Sue"
    Dim FindMe As String = "John"
    Dim Delimiter As String = ","
    
    Dim Pos As Int = Find_Position(NameList, FindMe , Delimiter, False)
 
Upvote 0

JamesGreaves

Active Member
Licensed User
Ok, I have done code for what i wanted, just sharing :)

B4X:
Sub Find_Position (ThisData As String, Find_This As String, Delimiter As String, CaseSensitive As Boolean) As Int
 
    If CaseSensitive=False Then
        ThisData=ThisData.ToUpperCase
        Find_This=Find_This.ToUpperCase
    End If
 
    Dim ThisRow() As String = Regex.Split(Delimiter, ThisData)
   
    Dim NotFound As Boolean = False
    Dim RowCount As Int = 0
    Do While RowCount < ThisRow.Length And NotFound = False
        If Find_This = ThisRow(RowCount).Trim Then NotFound = True
        RowCount = RowCount + 1
    Loop
   
    Return RowCount
   
End Sub

And you use it like this:

B4X:
Dim NameList As String = "Jack, John, Peter, Mary, Sue"
    Dim FindMe As String = "John"
    Dim Delimiter As String = ","
   
    Dim Pos As Int = Find_Position(NameList, FindMe , Delimiter, False)
OOPs, what if it doesn't find it :eek:
 
Upvote 0

JamesGreaves

Active Member
Licensed User
Here is the corrected version:

B4X:
Sub Find_Position (ThisData As String, Find_This As String, Delimiter As String, CaseSensitive As Boolean) As Int
 
    If CaseSensitive=False Then
        ThisData=ThisData.ToUpperCase
        Find_This=Find_This.ToUpperCase
    End If
 
    Dim ThisRow() As String = Regex.Split(Delimiter, ThisData)
    
    Dim NotFound As Boolean = False
    Dim RowCount As Int = 0
    Do While RowCount < ThisRow.Length And NotFound = False
        If Find_This = ThisRow(RowCount).Trim Then NotFound = True
        RowCount = RowCount + 1
    Loop
    
    If  NotFound = False Then
        Return 0
    Else
        Return RowCount
    End If
    
End Sub
 
Upvote 0

emexes

Expert
Licensed User
I feel like you're gunning for the Guinness World Record entry of Most Inefficient Program, but heck, what's the point of having billions of clock cycles if not to use them?
B4X:
Dim NameString As String = "Jack, John, Peter, Mary, Sue"
Dim NameList As List = Regex.Split("\s*,\s*", NameString)
Log(NameList.IndexOf("Mary") + 1)    'even returns 0 if not found ;-)
 
Last edited:
Upvote 0

emexes

Expert
Licensed User
Or, if willing to put your GBOWR entry at risk, you could replace this:
B4X:
Dim NotFound As Boolean = False
Dim RowCount As Int = 0
Do While RowCount < ThisRow.Length And NotFound = False
    If Find_This = ThisRow(RowCount).Trim Then NotFound = True
    RowCount = RowCount + 1
Loop
  
If  NotFound = False Then
    Return 0
Else
    Return RowCount
End If
with this:
B4X:
For I = 0 to ThisRow.Length - 1
    If Find_This = ThisRow(I).Trim Then
        Return I + 1    'convert 0 based to natural count
    End If
Next

Return 0    'Int Sub Returns 0 by default anyway, but no harm to be sure, to be sure
 
Upvote 0

emexes

Expert
Licensed User
B4X:
Do While RowCount < ThisRow.Length And NotFound = False
But I do like that you've put thought into making sure you don't search more elements than necessary :) There is an Exit command that will escape you out of a loop, that will usually achieve the same thing but without the temporary flag variable or check. In post #8 the Return is doing the escape for us; if we didn't want to exit the Sub at the same time, then we could use an Exit instead of the Return (after we've noted where we found Find_This)
 
Upvote 0

JamesGreaves

Active Member
Licensed User
I feel like you're gunning for the Guinness World Record entry of Most Inefficient Program, but heck, what's the point of having billions of clock cycles if not to use them?
B4X:
Dim NameString As String = "Jack, John, Peter, Mary, Sue"
Dim NameList As List = Regex.Split("\s*,\s*", NameString)
Log(NameList.IndexOf("Mary") + 1)    'even returns 0 if not found ;-)
Wow, that looks good!!
I have to consider 2 factors then:
1. Speed: which method is faster as it will be doing this a plenty.
2. Resources: which method used less memory/cpu as I don't want to bog down entry level devices.

I so appreciate your input.
Surely you have your own projects to do? :)
 
Upvote 0

JamesGreaves

Active Member
Licensed User
I feel like you're gunning for the Guinness World Record entry of Most Inefficient Program, but heck, what's the point of having billions of clock cycles if not to use them?
B4X:
Dim NameString As String = "Jack, John, Peter, Mary, Sue"
Dim NameList As List = Regex.Split("\s*,\s*", NameString)
Log(NameList.IndexOf("Mary") + 1)    'even returns 0 if not found ;-)
I am interested in the search Pattern("\s*,\s*") you use but cannot find documentation on all the options.
I discovered that "\s" is for white space and I understand ? and * from DOS days.

Any idea where I can find the full list of options?
 
Upvote 0

emexes

Expert
Licensed User
1. Speed: which method is faster as it will be doing this a plenty.
Main thing will be: construct the list once. And consider using a Map, which probably finds the entry even faster, as long as you know *precisely* what you're looking for... if you tell it to look for "Mary" then it will find "Mary" ok, but *not* " Mary" with a space in front. On the plus side, you can store additional information for each entry.
2. Resources: which method used less memory/cpu as I don't want to bog down entry level devices.
If you're "only" storing hundreds of names, you'll be ok - just do what works best and don't worry about the memory. If you're storing the thousands of names, then it might be time to consider moving the list to a file or database.
I so appreciate your input.
No worries, I can sense that you're doing something useful with it at your end :)
Surely you have your own projects to do?
It's way past knockoff time here, I'm just winding down for the night.
 
Upvote 0

emexes

Expert
Licensed User
Upvote 0
Top