Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations Chriss Miller on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

String Array Search 2

Status
Not open for further replies.

jbenson001

Programmer
Jan 7, 2004
8,172
US
I am creating a 1-Dimensonal arry of strings like this:
Code:
Dim OTC() As String
OTC = MyString.Split(",")

What I would like to know is how to seach my array(OTC) for a specific value, and get the idex of it.
ie. OTC.Find("MyString") (Not working obviously)

If I type OTC., I see indexof, find,..etc, however the syntax is extreamly confusing, or is there something I am missing...

Thanks...
Jim
 
This may not be the best example - but hopefully shows you what is happening:

Code:
	Private Sub Button4_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button4.Click

		Dim arr() As String
		Dim a As String = "This, is, a, string, with, several, words"
		arr = a.Split(","c)

		'using Find
		WordToFind = "with"
		WordFoundAt = -1	'not found
		If Not Array.Find(arr, AddressOf FindWord) Is Nothing Then
			MessageBox.Show("Found at: " + WordFoundAt.ToString)
		Else
			MessageBox.Show("Not found")
		End If

		'using IndexOf
		MessageBox.Show(Array.IndexOf(arr, WordToFind).ToString)


	End Sub

	Private WordToFind As String
	Private WordFoundAt As Integer

	Private Function FindWord(ByVal w As String) As Boolean

		WordFoundAt += 1
		If w.Contains(WordToFind) Then
			Return True
		Else
			Return False
		End If

	End Function

With the standard .IndexOf you require an exact match, in other words, in the above example in the array "with" is actually " with" and as such will not be found.

Using the new methods you provide a function that returns true or false and within it you determine whether or not a match was found that meets your precise requirements.

[vampire][bat]
 
Wow, that's an interesting solution. The contains will give you slightly different behavior as "within" with return true for "with".

I would have gone for something like this:
Code:
Dim a As String = "This, is, a, string, with, several, words"
Dim arr() As String = a.tolower.trim.Split(",")

Dim WordToFind As String = "with"
Dim WordIndex = arr.indexof(WordToFind)

if WordIndex >=0 then
  msgbox WordToFind & " found at position " & WordIndex
end if

-Rick

VB.Net Forum forum796 forum855 ASP.NET Forum
[monkey]I believe in killer coding ninja monkeys.[monkey]
 
Hi, thank you for the response. I am however getting compiliation errors. I am trying to use your code using the Array syntax. Here is the error:
(On this line Array.Find(arr, AddressOf FindWord))

Error 1 'AddressOf' operand must be the name of a method (without parentheses).

 
Thanks Rick, but I get this syntax error on the line
Dim WordIndex = arr.IndexOf(WordToFind)
Error 1 Overload resolution failed because no accessible 'IndexOf' accepts this number of arguments.

Not sure if it matters guys, but I am using vb.net 2.0

Jim
 
jbenson001, have you included the FindWord function that I included. By the way, I tested the code first and then copied and pasted.


Rick, two things:
1) Neither of my solutions change the source input string.
2) I made the point of finding pseudo-matches by looking for "with" where the string in the array was actually " with".

The new methods, although not in the least intuitive are very powerful. You are able to control exactly what constitues a match according to your precise criteria. IndexOf does an exact match - and only an exact match.


Hope this helps.

[vampire][bat]
 
jbenson001, Find and the new generics types were introduced in 2005. IndexOf is a hangover from the old primative way of doing things [wink]

[vampire][bat]
 
Sorry Rick, I missed copying that in from the other post. I will give it a try.
 
Just to expand slightly, this shows how to use FindAll

Code:
	Private Sub Button4_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button4.Click

		Dim arr() As String
		Dim a As String = "This, is, a, string, with, several, words"
		arr = a.Split(","c)

		'using Find
		WordToFind = " words"
		WordFoundAt = -1	'not found
		If Not Array.Find(arr, AddressOf FindWord) Is Nothing Then
			MessageBox.Show("Found at: " + WordFoundAt.ToString)
		Else
			MessageBox.Show("Not found")
		End If

		'using IndexOf
		MessageBox.Show(Array.IndexOf(arr, WordToFind).ToString)


	End Sub

	Private WordToFind As String
	Private WordFoundAt As Integer

	Private Function FindWord(ByVal w As String) As Boolean

		WordFoundAt += 1
		If w.Contains(WordToFind) Then
			Return True
		Else
			Return False
		End If

	End Function


	Private Sub Button5_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button5.Click

		Dim arr() As String
		Dim a As String = "This, is, a, string, with, several, words"
		arr = a.Split(","c)

		'using Find
		WordToFind = "is"
		WordFoundAt = -1	'not found
		FoundWordCount = 0
		FoundWords = Array.FindAll(arr, AddressOf FindAllOccurancesOfWord)
		MessageBox.Show(FoundWordCount.ToString + " occurances")
		If FoundWordCount > 0 Then
			For b As Integer = 0 To FoundWordCount - 1
				MessageBox.Show(FoundWords(b) + " at " + FoundIndices(b).ToString)
			Next
		End If
	End Sub

	Private FoundIndices() As Integer
	Private FoundWords() As String
	Private FoundWordCount As Integer

	Private Function FindAllOccurancesOfWord(ByVal w As String) As Boolean

		WordFoundAt += 1
		If w.Contains(WordToFind) Then
			FoundWordCount += 1
			Array.Resize(FoundIndices, FoundWordCount)
			FoundIndices(FoundWordCount - 1) = WordFoundAt
			Return True
		Else
			Return False
		End If

	End Function


Hope this helps.

[vampire][bat]
 
Thank you both so much for the help and the GREAT examples, I've got it working now!!!

Jim :)

 
1) Neither of my solutions change the source input string.

True, but neither did mine ;)

2) I made the point of finding pseudo-matches by looking for "with" where the string in the array was actually " with".

Yes, but pseudo-matches and exact-matches are not the same thing. This if the goal was to find "with" and only "with", then a pseudo match would not be acceptable.

I'm not saying your way is wrong, it is just different than what I first thought of. It is a great example of a custom compare.

I haven't played with 2k5 at all, but I would find it hard to believe that Collection.IndexOf is being deprecated. Unless you meant "Primitive" in the sense of fundamental types (ie: Char, Int, Dec, etc...) in which case, sure, IndexOf is a primitive member of the collection object.

JBenson, sorry about my incorrect syntax, was rushing to meet some co-workers for lunch and completely botched that line up! It should be:
Code:
Dim WordIndex = array.indexof(arr, WordToFind)

-Rick

VB.Net Forum forum796 forum855 ASP.NET Forum
[monkey]I believe in killer coding ninja monkeys.[monkey]
 
Rick, sorry, I misread your ToLower.

But this covers:

CaseInsensitive (match based on Option Compare or manually adjusted by ToLower / ToUpper)
Case Sensitive (exact match regardless of Option Compare)
and Contains (match based on Option Compare or manually adjusted by ToLower / ToUpper)

Code:
	Private Enum MatchTypeEnum
		CaseInsensitive
		CaseSensitive
		Contains
	End Enum

	Private MatchType As MatchTypeEnum

	Private Sub Button4_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button4.Click

		Dim arr() As String
		Dim a As String = "This, is, a, string, with, several, words"
		arr = a.Split(","c)

		'using Find
		WordToFind = TextBox1.Text

		If RadioButton1.Checked Then MatchType = MatchTypeEnum.CaseInsensitive
		If RadioButton2.Checked Then MatchType = MatchTypeEnum.CaseSensitive
		If RadioButton3.Checked Then MatchType = MatchTypeEnum.Contains

		WordFoundAt = -1	'not found
		If Not Array.Find(arr, AddressOf FindWord) Is Nothing Then
			MessageBox.Show("Found at: " + WordFoundAt.ToString)
		Else
			MessageBox.Show("Not found")
		End If

	End Sub

	Private WordToFind As String
	Private WordFoundAt As Integer

	Private Function FindWord(ByVal w As String) As Boolean

		WordFoundAt += 1
		Dim found As Boolean = False

		Select Case MatchType
			Case MatchTypeEnum.CaseInsensitive
				found = w.ToLower = WordToFind.ToLower
			Case MatchTypeEnum.CaseSensitive
				found = String.CompareOrdinal(w, WordToFind) = 0
			Case MatchTypeEnum.Contains
				found = w.ToLower.Contains(WordToFind.ToLower)
		End Select

		If found Then
			Return True
		Else
			Return False
		End If

	End Function


Hope this helps.

[vampire][bat]
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top