VB-2008 How to retrieve strings with largest numerical suffix in an array? - vb.net

I got the following strings arrays
a.csv
a-1.csv
a-2.csv
a-3.csv
ab.csv
ab-1.csv
ab-2.csv
cccc.csv
cccc-1.csv
d.csv
In this strings arrays, it stores a series of test data, the naming conversion for each test data is as follows,
'unit name'+'-'+('suffix in single digit number')+'.csv'
The length of the unit name could be any length, but the suffix can only be single-digit number (1-9). For example for unit a, it undergoes 4 test in total, which are a.csv, a-1.csv, a-2.csv and a-3.csv. But because all of the first three test fails the specs, therefore only the last test data will be retrieved for analysis, which is a-3.csv.
So, for the final output, I only need those data which have the largest suffix for each unit, which gives me the output string array:
a-3.csv
ab-2.csv
cccc-1.csv
d.csv
How should I choose the correct files from the input string array according to the rules to get those test data only got the largest suffix.

Private Function Suffix(ByVal s As String) As String
s = IO.Path.GetFileNameWithoutExtension(s)
Dim pos = s.LastIndexOf("-"c)
Return If(pos = -1, s, s.Substring(0, pos))
End Function
Private Function Value(ByVal s As String) As Integer
s = IO.Path.GetFileNameWithoutExtension(s)
Dim pos = s.LastIndexOf("-"c)
Return If(pos = -1, 0, Integer.Parse(s.Substring(pos + 1)))
End Function
Dim arr() As String = New String() {"a.csv", "a-1.csv", "a-2.csv", "a-3.csv", "ab.csv", "ab-1.csv", "ab-2.csv", "cccc.csv", "cccc-1.csv", "d.csv"}
Dim largest = arr.GroupBy(Function(s) Suffix(s), StringComparer.OrdinalIgnoreCase) _
.Select(Function(g) g.OrderByDescending(Function(s) Value(s)).First())
For Each s In largest
Console.WriteLine(s)
Next

Though your question is not clear but I think you want to have the latest occurrence to be stored in a separate array. Here is how you can achieve that:
Dim arrayInput As List(Of String) = New List(Of String)
arrayInput.Add("a.csv")
arrayInput.Add("a-1.csv")
arrayInput.Add("a-2.csv")
arrayInput.Add("a-3.csv")
arrayInput.Add("b.csv")
arrayInput.Add("b-1.csv")
arrayInput.Add("b-2.csv")
arrayInput.Add("c.csv")
arrayInput.Add("c-1.csv")
arrayInput.Add("d.csv")
Dim arrayOutput As List(Of String) = New List(Of String)
Dim strTemp As String = arrayInput(0)
Dim startingChar As String = strTemp.Substring(0, 1)
For Each item As String In arrayInput
If Not startingChar.Equals(item.Substring(0, 1), StringComparison.OrdinalIgnoreCase) Then
arrayOutput.Add(strTemp)
startingChar = item.Substring(0, 1)
End If
strTemp = item
Next
arrayOutput.Add(strTemp)
You have the required result in arrayOutput. Let me know if you wanted something else instead.

Related

How to properly turn this string into a correct structure?

Structure WeightElement 'The Weights are stored in an array of Weight Elemenets, which are used as a tree
Dim LowPointer As Integer
Dim HighPointer As Integer
Dim TraitPointer As Integer 'This pointer allows another tree to be appended to certain elements, for the sake of dependent traits
Dim Values As WeightedTrait()
Dim Num As Integer 'The Weight Elements are named by numbers for ease of comparison
End Structure
Structure WeightedTrait
Dim TraitName As String 'This is the value that is displayed to the user when a character is made
Dim TraitNum As Integer 'The trait number is used to find the correct element in trait sub-trees
Dim WeightValue As Decimal
End Structure
Function ChewQuery(QueryList As String)
'This function takes in a string and partitions it into a weight tree
Dim ElementList() As String
ElementList = QueryList.Split(";")
Dim LoadedWeight(ElementList.Length) As WeightElement
For x = 0 To ElementList.Length - 1
'Using this method, in which the front portion of the query is repeatedly removed, allows for a simpler query structure, so that we don't need to partition between the pointers and values
LoadedWeight(x).LowPointer = CInt(BiteQuery(ElementList(x)))
LoadedWeight(x).HighPointer = CInt(BiteQuery(ElementList(x)))
LoadedWeight(x).TraitPointer = CInt(BiteQuery(ElementList(x)))
LoadedWeight(x).Num = CInt(BiteQuery(ElementList(x)))
ChewQueryValues(ElementList(x), LoadedWeight(x))
Next
Return LoadedWeight
End Function
Function BiteQuery(ByRef QueryList As String)
Dim Marker As Integer
Dim Bite As String
'This function partitions the input string around the first comma
'It returns the section before the comma, and stores the section behind the comma as the new value for the string
Try
Marker = InStr(QueryList, ",")
Bite = Left(QueryList, Marker - 1)
Marker = Len(QueryList) - Marker
QueryList = Right(QueryList, Marker)
Catch
'This is used in the case that a list without a comma is input
Bite = QueryList
QueryList = ""
End Try
Return Bite
End Function
Sub ChewQueryValues(ByRef QueryList As String, ByRef LoadedWeight As WeightElement)
LoadedWeight.Values = {}
While Len(QueryList) > 0
'This While loop is so that an arbitrary number of values can be inserted
'Because BiteQuery takes in functions by reference, each loop reduces the length of the string until it is empty
ReDim Preserve LoadedWeight.Values(LoadedWeight.Values.Length + 1)
LoadedWeight.Values(LoadedWeight.Values.Length - 1).TraitName = BiteQuery(QueryList)
LoadedWeight.Values(LoadedWeight.Values.Length - 1).TraitNum = CInt(BiteQuery(QueryList))
LoadedWeight.Values(LoadedWeight.Values.Length - 1).WeightValue = CDec(BiteQuery(QueryList))
End While
End Sub
These subroutines should transform a properly formatted string into a WeightElement array. The string I am using is:
1,2,0,5,Black,26,1,White,30,1,EastAsian,27,1,SouthAsian,28,1,MiddleEastern,29,1;3,4,25,3,N/A,0,1;28,5,6,13,N/A,0,1;-1,7,0,1,Male,16,1,Female,17,1,Non-Binary,18,1;-1,-1,8,4,N/A,0,1;-1,34,9,15,N/A,0,1;10,11,0,28,Light,-1,1,Medium,-1,1;-1,-1,12,2,N/A,0,1;13,14,0,21,Andro,19,1,Gyno,20,1,A,21,1,Bi,22,1,Pan,23,1;15,16,0,28,Straight,-1,1,Wavy,-1,1,Curly,-1,1;-1,17,0,26,Light,-1,1,Medium,-1,1,Dark,-1,1;18,-1,0,30,Pale,-1,1,Light,-1,1;19,20,0,17,Male,31,1,Female,32,1,Intersex,33,1;-1,21,0,19,Andro,19,1,Gyno,20,1,A,21,1,Bi,22,1,Pan,23,1;22,-1,0,23,Andro,19,1,Gyno,20,1,A,21,1,Bi,22,1,Pan,23,1;-1,23,0,26,Curly,-1,1,Coily,-1,1;24,-1,0,30,Straight,-1,1,Wavy,-1,1,Curly,-1,1;-1,-1,0,27,Pale,-1,1,Light,-1,1,Medium,-1,1;-1,-1,0,29,Pale,-1,1,Light,-1,1,Medium,-1,1;-1,-1,0,16,Male,31,1,Female,32,1,Intersex,33,1;-1,-1,0,18,Male,31,1,Female,32,1,Intersex,33,1;-1,-1,0,20,Andro,19,1,Gyno,20,1,A,21,1,Bi,22,1,Pan,23,1;-1,-1,0,22,Andro,19,1,Gyno,20,1,A,21,1,Bi,22,1,Pan,23,1;-1,-1,0,27,Straight,-1,1,Wavy,-1,1;-1,-1,0,29,Straight,-1,1,Wavy,-1,1,Curly,-1,1;26,27,0,17,Andro,19,1,Gyno,20,1,A,21,1,Bi,22,1,Pan,23,1;-1,-1,0,16,Andro,19,1,Gyno,20,1,A,21,1,Bi,22,1,Pan,23,1;-1,-1,0,18,Andro,19,1,Gyno,20,1,A,21,1,Bi,22,1,Pan,23,1;29,30,0,8,Albinism,-1,1,ChronicFatigue,-1,1,Dwarfism,-1,1;-1,31,0,6,Autistic,-1,1,ADHD,-1,1,OCD,-1,1,Tourrette,-1,1,Epilepsy,-1,1;32,33,35,10,N/A,0,1;-1,-1,0,7,OneArmAbsent,-1,1,BothArmsAbsent,-1,1,OneHandwithAnomalies,-1,1,BothHandswithAnomalies,-1,1,OneLegAbsent,26,1,BothLegsAbsent,26,1;-1,-1,36,9,N/A,0,1;-1,-1,0,11,GoodHearing,-1,1,HardofHearing,-1,1,Deaf,-1,1,NoHearing,-1,1;-1,-1,0,34,Scars,-1,1,NaturalAnomalies,-1,1,OneEyeAbsent,-1,1,BothEyesAbsent,-1,1;-1,37,0,0,GoodVision,-1,1,Blind,-1,1,NoVision,-1,1;-1,38,0,0,Unaided,-1,1,Cane,-1,1,Wheelchair,-1,1,Full-TimeWheelchair,-1,1;-1,-1,0,25,N/A,0,1;-1,-1,0,26,Unaided,-1,1,Cane,-1,1,Wheelchair,-1,1,Full-TimeWheelchair,-1,1
The format is that the first four values between each semicolon are the low pointer, high pointer, trait pointer, and Number, in that order. After this point are the values, with the trait name, trait number, and weight value, repeating in that order
When I use this string, the program decides to return a WeightElement array of the correct length, but where all the values are 0 or empty strings. How do I make it produce a proper WeightElement, as by the format above?

Get a specific value from the line in brackets (Visual Studio 2019)

I would like to ask for your help regarding my problem. I want to create a module for my program where it would read .txt file, find a specific value and insert it to the text box.
As an example I have a text file called system.txt which contains single line text. The text is something like this:
[Name=John][Last Name=xxx_xxx][Address=xxxx][Age=22][Phone Number=8454845]
What i want to do is to get only the last name value "xxx_xxx" which every time can be different and insert it to my form's text box
Im totally new in programming, was looking for the other examples but couldnt find anything what would fit exactly to my situation.
Here is what i could write so far but i dont have any idea if there is any logic in my code:
Dim field As New List(Of String)
Private Sub readcrnFile()
For Each line In File.ReadAllLines(C:\test\test_1\db\update\network\system.txt)
For i = 1 To 3
If line.Contains("Last Name=" & i) Then
field.Add(line.Substring(line.IndexOf("=") + 2))
End If
Next
Next
End Sub
Im
You can get this down to a function with a single line of code:
Private Function readcrnFile(fileName As String) As IEnumerable(Of String)
Return File.ReadLines(fileName).Where(Function(line) RegEx.IsMatch(line, "[[[]Last Name=(?<LastName>[^]]+)]").Select(Function(line) RegEx.Match(line, exp).Groups("LastName").Value)
End Function
But for readability/maintainability and to avoid repeating the expression evaluation on each line I'd spread it out a bit:
Private Function readcrnFile(fileName As String) As IEnumerable(Of String)
Dim exp As New RegEx("[[[]Last Name=(?<LastName>[^]]+)]")
Return File.ReadLines(fileName).
Select(Function(line) exp.Match(line)).
Where(Function(m) m.Success).
Select(Function(m) m.Groups("LastName").Value)
End Function
See a simple example of the expression here:
https://dotnetfiddle.net/gJf3su
Dim strval As String = " [Name=John][Last Name=xxx_xxx][Address=xxxx][Age=22][Phone Number=8454845]"
Dim strline() As String = strval.Split(New String() {"[", "]"}, StringSplitOptions.RemoveEmptyEntries) _
.Where(Function(s) Not String.IsNullOrWhiteSpace(s)) _
.ToArray()
Dim lastnameArray() = strline(1).Split("=")
Dim lastname = lastnameArray(1).ToString()
Using your sample data...
I read the file and trim off the first and last bracket symbol. The small c following the the 2 strings tell the compiler that this is a Char. The braces enclosed an array of Char which is what the Trim method expects.
Next we split the file text into an array of strings with the .Split method. We need to use the overload that accepts a String. Although the docs show Split(String, StringSplitOptions), I could only get it to work with a string array with a single element. Split(String(), StringSplitOptions)
Then I looped through the string array called splits, checking for and element that starts with "Last Name=". As soon as we find it we return a substring that starts at position 10 (starts at zero).
If no match is found, an empty string is returned.
Private Function readcrnFile() As String
Dim LineInput = File.ReadAllText("system.txt").Trim({"["c, "]"c})
Dim splits = LineInput.Split({"]["}, StringSplitOptions.None)
For Each s In splits
If s.StartsWith("Last Name=") Then
Return s.Substring(10)
End If
Next
Return ""
End Function
Usage...
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
TextBox1.Text = readcrnFile()
End Sub
You can easily split that line in an array of strings using as separators the [ and ] brackets and removing any empty string from the result.
Dim input As String = "[Name=John][Last Name=xxx_xxx][Address=xxxx][Age=22][Phone Number=8454845]"
Dim parts = input.Split(New Char() {"["c, "]"c}, StringSplitOptions.RemoveEmptyEntries)
At this point you have an array of strings and you can loop over it to find the entry that starts with the last name key, when you find it you can split at the = character and get the second element of the array
For Each p As String In parts
If p.StartsWith("Last Name") Then
Dim data = p.Split("="c)
field.Add(data(1))
Exit For
End If
Next
Of course, if you are sure that the second entry in each line is the Last Name entry then you can remove the loop and go directly for the entry
Dim data = parts(1).Split("="c)
A more sophisticated way to remove the for each loop with a single line is using some of the IEnumerable extensions available in the Linq namespace.
So, for example, the loop above could be replaced with
field.Add((parts.FirstOrDefault(Function(x) x.StartsWith("Last Name"))).Split("="c)(1))
As you can see, it is a lot more obscure and probably not a good way to do it anyway because there is no check on the eventuality that if the Last Name key is missing in the input string
You should first know the difference between ReadAllLines() and ReadLines().
Then, here's an example using only two simple string manipulation functions, String.IndexOf() and String.Substring():
Sub Main(args As String())
Dim entryMarker As String = "[Last Name="
Dim closingMarker As String = "]"
Dim FileName As String = "C:\test\test_1\db\update\network\system.txt"
Dim value As String = readcrnFile(entryMarker, closingMarker, FileName)
If Not IsNothing(value) Then
Console.WriteLine("value = " & value)
Else
Console.WriteLine("Entry not found")
End If
Console.Write("Press Enter to Quit...")
Console.ReadKey()
End Sub
Private Function readcrnFile(ByVal entry As String, ByVal closingMarker As String, ByVal fileName As String) As String
Dim entryIndex As Integer
Dim closingIndex As Integer
For Each line In File.ReadLines(fileName)
entryIndex = line.IndexOf(entry) ' see if the marker is in our line
If entryIndex <> -1 Then
closingIndex = line.IndexOf(closingMarker, entryIndex + entry.Length) ' find first "]" AFTER our entry marker
If closingIndex <> -1 Then
' calculate the starting position and length of the value after the entry marker
Dim startAt As Integer = entryIndex + entry.Length
Dim length As Integer = closingIndex - startAt
Return line.Substring(startAt, length)
End If
End If
Next
Return Nothing
End Function

New to programming language, need help to read a .dat file into array Vs VB, console .net framework

I am trying to read from a data file called TXT.dat and store the circled values into a separate array's using the type of commands I have used. I cannot use streamreader,streamwriter this is what I am learning at university but we were taught to read an array not certain values as I will be tested using a file which has
2 factorial values from a single file and store int two arrays.
I have spent hours trying before going to paid sites who always answer with i/o streamreader which doesnt help
.dat file i created to practice
MY CODE
Sub Main()
Const i_val As Integer = 6
Dim j As Integer = 6 'loop readers
Dim Arayn_Fact(i_val - 1) As Double 'array for 2nd value per line
Dim Aray_Fact2n(j - 1) As Double 'array for 4th value per line
Read_Values(i_val - 1, Arayn_Fact)
End Sub
Sub Read_Values(ByVal i As Integer, ByRef _A() As Double)
Dim fid1 As Integer = FreeFile()
Dim fid2 As Integer = FreeFile() + 1
Dim tmp As Double
FileOpen(fid1, "TXT.dat", OpenMode.Input, OpenAccess.Read)
For i = 0 To 5 Step 1
Input(fid1, tmp)
Input(fid1, _A(i))
Next i
FileClose(fid1)
Console.ReadKey()
End Sub
Without getting too fancy, here's some very basic code to do what you've outlined:
Sub Main()
Dim fileName As String = "txt.dat"
Dim Aray_Fact2() As Integer 'array for 2nd value per line
Dim Aray_Fact4() As Integer 'array for 4th value per line
Dim list2 As New List(Of Integer)
Dim list4 As New List(Of Integer)
Dim lines() As String = System.IO.File.ReadAllLines(fileName)
For Each line As String In lines
Dim values() As String = line.Split(",")
If values.Length >= 3 Then
Dim f2, f4 As Integer
If Integer.TryParse(values(1), f2) AndAlso Integer.TryParse(values(3), f4) Then
list2.Add(f2)
list4.Add(f4)
Else
Console.WriteLine("Invalid value in line: " & line)
End If
Else
Console.WriteLine("Invalid number of entries in line: " & line)
End If
Next
Aray_Fact2 = list2.ToArray
Aray_Fact4 = list4.ToArray
Console.WriteLine("Aray_Fact2: " & String.Join(",", Aray_Fact2))
Console.WriteLine("Aray_Fact4: " & String.Join(",", Aray_Fact4))
Console.Write("Press Enter to Quit...")
Console.ReadLine()
End Sub
If you are completely against the use of Lists and ToArray, then you'd have to read the file TWICE. Once to determine how many lines are in the file so you can dimension the arrays to the correct size. Then another time to actually read the values and populate the arrays.
First, some style things. Passing the array ByRef is incorrect. Arrays are already reference types, and so passing ByVal still passes the reference to the array object. But don't even pass the array in the first place. It's better practice to let the Read_Values() method create and return the array to the calling function.
And no one uses that ancient/ganky FileOpen() API anymore. I mean that. NO. ONE. It's not even appropriate for teaching, as the Stream types are closer to what the low level operating system/file system are doing. If you can't use StreamReader and friends, there are still better options out there.
Sub Main()
Dim Array_Fact() As Double = Read_Values("TXT.dat", 1)
Dim Array_Fact2n() As Double = Read_Values("TXT.dat", 3)
Console.ReadKey(True)
End Sub
Function Read_Values(filePath As String, position As Integer) As Double()
Dim lines() As String = File.ReadAllLines(filePath) 'Look Ma, no StreamReader
Dim result(lines.Length - 1) As Double
For i As Integer = 0 To Lines.Length - 1
result(i) = Double.Parse(lines(i).Split(",")(position).Trim())
Next line
Return result
End Function
But what I'd really do is keep the 2nd and 4th values in the same collection and read everything in one pass through the file. This uses features like Generics, Tuples, Lambdas+Linq, and more that you won't get to for some time, but I feel like it's useful to show you where you're going:
Sub Main()
Dim Facts = Read_Values("TXT.dat")
Console.WriteLine(String.Join(",",Facts.Select(Function(f) $"({f.Item1}:{f.Item2})")))
Console.ReadKey(True)
End Sub
Function Read_Values(filePath As String) As IEnumerable(Of (Double, Double))
Return File.ReadLines(filePath).Select(
Function(line) 'Poor man's CSV. In real code, I'd pull in a CSV parser from NuGet
Dim fields = line.Split(",")
Return (Double.Parse(fields(1).Trim()), Double.Parse(fields(3).Trim()))
End Function
)
End Function

Splitting file into parts for dictionary use

I have an uploaded file, displaying
Han 33.3
Han 5.66
Han 8.3
Chewbacca 99.4
Chewbacca 100.3
Chewbacca 98.1
I need to make an average for each han and Chewbacca using a dictionary, but first I have to split the list in order to do that. How do I split them for this purpose.
I'm making the assumption that the whitespace between the name and quantity is a single space. I'm also calling your values "scores" and Han and Chewbacca "players" for my example solution. The result splits the line into individual key-value pairs; each key represents the list of values found; it:
Imports System.IO
Dim pathToYourFile As String = "Path to your file with file name"
Dim f As StreamReader = File.OpenText(pathToYourFile)
Dim fileText As String = f.ReadToEnd
f.Close()
Dim singleSpace As String = " " 'single space between quotes
Dim playerScores As New SortedDictionary(Of String, List(Of Double))
Dim lines() As String = fileText.Split(vbCrLf.ToCharArray())
For i As Integer = 0 To lines.Length - 1
Dim scoreLine() As String = lines(i).Split(" ".ToCharArray())
Dim playerName As String = scoreLine(0)
Dim score As Double = Double.Parse(scoreLine(1))
If playerScores.ContainsKey(playerName) Then
playerScores(playerName).Add(score)
Else
Dim list As New List(Of Double)
list.Add(score)
playerScores.Add(playerName, list)
End If
Next i
Try this:
Public Class DataClass
Public Property Name() As String
Public Property Value() As Decimal
End Class
' ...
Public Shared Function GetAverageDict(lines As IEnumerable(Of String)) _
As Dictionary(Of String, Decimal)
Dim lst As New List(Of DataClass)()
For Each line As String In lines
Dim lastSpaceIndex = line.LastIndexOf(" ")
If (lastSpaceIndex >= 0) Then
Dim name = line.Substring(0, lastSpaceIndex).Trim()
Dim value = Decimal.Parse(line.Substring(lastSpaceIndex + 1), _
System.Globalization.CultureInfo.InvariantCulture)
lst.Add(New DataClass() With { .Name = name, .Value = value })
End If
Next
Dim averages = From g In From x In lst _
Group x By key = x.Name _
Select New With { .Name = key, _
.Average = Group.Average(Function(y) y.Value) }
Return averages.ToDictionary(Function(x) x.Name, Function(y) y.Average)
End Function
The function first gets the parts from each line. It assumes that the last space is the separator between the parts. This way, the name can also contain space characters.
The data is collected in a list that is afterwards grouped by the name. By calling ToDictionary the result of the grouping operation is converted in a dictionary.
Call the function like this:
Dim dict = GetAverageDict(System.IO.File.GetLines(filePath))

How can I search an array in VB.NET?

I want to be able to effectively search an array for the contents of a string.
Example:
dim arr() as string={"ravi","Kumar","Ravi","Ramesh"}
I pass the value is "ra" and I want it to return the index of 2 and 3.
How can I do this in VB.NET?
It's not exactly clear how you want to search the array. Here are some alternatives:
Find all items containing the exact string "Ra" (returns items 2 and 3):
Dim result As String() = Array.FindAll(arr, Function(s) s.Contains("Ra"))
Find all items starting with the exact string "Ra" (returns items 2 and 3):
Dim result As String() = Array.FindAll(arr, Function(s) s.StartsWith("Ra"))
Find all items containing any case version of "ra" (returns items 0, 2 and 3):
Dim result As String() = Array.FindAll(arr, Function(s) s.ToLower().Contains("ra"))
Find all items starting with any case version of "ra" (retuns items 0, 2 and 3):
Dim result As String() = Array.FindAll(arr, Function(s) s.ToLower().StartsWith("ra"))
-
If you are not using VB 9+ then you don't have anonymous functions, so you have to create a named function.
Example:
Function ContainsRa(s As String) As Boolean
Return s.Contains("Ra")
End Function
Usage:
Dim result As String() = Array.FindAll(arr, ContainsRa)
Having a function that only can compare to a specific string isn't always very useful, so to be able to specify a string to compare to you would have to put it in a class to have somewhere to store the string:
Public Class ArrayComparer
Private _compareTo As String
Public Sub New(compareTo As String)
_compareTo = compareTo
End Sub
Function Contains(s As String) As Boolean
Return s.Contains(_compareTo)
End Function
Function StartsWith(s As String) As Boolean
Return s.StartsWith(_compareTo)
End Function
End Class
Usage:
Dim result As String() = Array.FindAll(arr, New ArrayComparer("Ra").Contains)
Dim inputString As String = "ra"
Enumerable.Range(0, arr.Length).Where(Function(x) arr(x).ToLower().Contains(inputString.ToLower()))
If you want an efficient search that is often repeated, first sort the array (Array.Sort) and then use Array.BinarySearch.
In case you were looking for an older version of .NET then use:
Module Module1
Sub Main()
Dim arr() As String = {"ravi", "Kumar", "Ravi", "Ramesh"}
Dim result As New List(Of Integer)
For i As Integer = 0 To arr.Length
If arr(i).Contains("ra") Then result.Add(i)
Next
End Sub
End Module
check this..
string[] strArray = { "ABC", "BCD", "CDE", "DEF", "EFG", "FGH", "GHI" };
Array.IndexOf(strArray, "C"); // not found, returns -1
Array.IndexOf(strArray, "CDE"); // found, returns index
compare properties in the array if one matches the input then set something to the value of the loops current position, which is also the index of the current looked up item.
simple eg.
dim x,y,z as integer
dim aNames, aIndexes as array
dim sFind as string
for x = 1 to length(aNames)
if aNames(x) = sFind then y = x
y is then the index of the item in the array, then loop could be used to store these in an array also so instead of the above you would have:
z = 1
for x = 1 to length(aNames)
if aNames(x) = sFind then
aIndexes(z) = x
z = z + 1
endif
VB
Dim arr() As String = {"ravi", "Kumar", "Ravi", "Ramesh"}
Dim result = arr.Where(Function(a) a.Contains("ra")).Select(Function(s) Array.IndexOf(arr, s)).ToArray()
C#
string[] arr = { "ravi", "Kumar", "Ravi", "Ramesh" };
var result = arr.Where(a => a.Contains("Ra")).Select(a => Array.IndexOf(arr, a)).ToArray();
-----Detailed------
Module Module1
Sub Main()
Dim arr() As String = {"ravi", "Kumar", "Ravi", "Ramesh"}
Dim searchStr = "ra"
'Not case sensitive - checks if item starts with searchStr
Dim result1 = arr.Where(Function(a) a.ToLower.StartsWith(searchStr)).Select(Function(s) Array.IndexOf(arr, s)).ToArray
'Case sensitive - checks if item starts with searchStr
Dim result2 = arr.Where(Function(a) a.StartsWith(searchStr)).Select(Function(s) Array.IndexOf(arr, s)).ToArray
'Not case sensitive - checks if item contains searchStr
Dim result3 = arr.Where(Function(a) a.ToLower.Contains(searchStr)).Select(Function(s) Array.IndexOf(arr, s)).ToArray
Stop
End Sub
End Module
Never use .ToLower and .ToUpper.
I just had problems in Turkey where there are 4 "i" letters. When using ToUpper I got the wrong "Ì" one and it fails.
Use invariant string comparisons:
Const LNK as String = "LINK"
Dim myString = "Link"
Bad:
If myString.ToUpper = LNK Then...
Good and works in the entire world:
If String.Equals(myString, LNK , StringComparison.InvariantCultureIgnoreCase) Then...
This would do the trick, returning the values at indeces 0, 2 and 3.
Array.FindAll(arr, Function(s) s.ToLower().StartsWith("ra"))