Check If value appears twice in array - arrays

I have and array and i want to check if my Dim value is contains in array but i need to check if it appears twice.
Example:
Dim value as String = "AST"
Dim zone_check_list() As String = {"AMST","AST","AST","EET","EDT"}
'if "AST" appeared twice then i will show message box

How about using LINQ :
Imports System.Linq
Dim value as String = "AST"
Dim zone_check_list() As String = {"AMST","AST","AST","EET","EDT"}
Dim isAppearTwice As Boolean = (zone_check_list.Count(Function(x) x = value) = 2)
Console.WriteLine(isAppearTwice)

Related

Correct way to show an output from for loop in a label

hi I have a code that can transform the lower case letters of each element of a String array using for loop. the problem is only the last element is appearing on the output(label) but shows fine on the debug output
Dim lst() = {"apple", "banana", "cherry"}
For Each item As String In lst
Dim array() As Char = item.ToCharArray
array(0) = Char.ToUpper(array(0))
Dim newS = New String(array)
Dim value As String = String.Join("/", newS)
TextBox1.Text = value
Debug.Write(value)
Output.Text = value
Next
Debug.WriteLine("")
this is the problem that occurs, it changes the label into an into the last element with the uppercase letter as it it is meant to be, but
i want the output to be the same as the debug output which is
AppleBananaCherry
You don't need to explicitly define a Char array. A String has a Char(index) property which is the Default property. We can use this directly on the String. MyString(index)
We assign the new String that is returned by the Replace method to an element of the array. index starts at 0, the default value of an Integer, and is incremented on each iteration of the For Each loop.
Finally, after the For Each, we assign the Join to the label.
Your code and where it went wrong.
Private Sub Button4_Click(sender As Object, e As EventArgs) Handles Button4.Click
Dim lst() = {"apple", "banana", "cherry"}
For Each item As String In lst
Dim array() As Char = item.ToCharArray
array(0) = Char.ToUpper(array(0))
Dim newS = New String(array)
Dim value As String = String.Join("/", newS)
TextBox1.Text = value 'Overwrites the last value you assigned to the Text property
Debug.Write(value) 'Adds on to the last value it wrote in the debug window.
Label1.Text = value 'Overwrites the last value you assigned to the Text property
Next
Debug.WriteLine("")
End Sub
Corrected code.
Private Sub Button3_Click(sender As Object, e As EventArgs) Handles Button3.Click
Dim lst = {"apple", "banana", "cherry"}
Dim index As Integer
For Each item As String In lst
lst(index) = item.Replace(item(0), Char.ToUpper(item(0)))
index += 1
Next
Label1.Text = String.Join("", lst)
End Sub
This is WinForms but the code you care about shouldn't be any different, just the Event procedure format.
You can even make it in a single line without an explicit loop.
Dim lst = {"apple", "banana", "cherry"}
Output.Text = String.Join("", lst.Select(Function(x) CultureInfo.CurrentCulture.TextInfo.ToTitleCase(x))))
While it seems very "smart" there are a couple of things to consider.
If the original list is very big (meaning thousands of strings) this
is less efficient because the Linq Select and the subsequent Join
will create a new list doubling the memory used.
If you want to change more than the first character, the ToTitleCase
method cannot work

Adding Item to Array (VB 2008)

The objective of the program is to interpret hockey statistics from a file using StreamReader and then display an added column of points. The following code kinda does so, however it’s ineffective in the sense that it doesn’t add the points value to the array - it separately outputs it. Looking for assistance as to how it would be possible to incorporate the points value into aryTextFile();
Dim hockeyFile, LineOfText, aryTextFile() As String
Dim i As Integer
Dim nameText(), NumberText(), goalsText(), assistsText(), GamesWonText() As String
Dim IntAssists(), IntGoals(), PointsText() As Single
hockeyFile = "C:\Users\Bob\Downloads\hockey.txt" 'state location of file
Dim objReader As New System.IO.StreamReader(hockeyFile) 'objReader can read hockeyFile
For i = 0 To objReader.Peek() <> -1 'reads each line seperately, ends when there is no more data to read
LineOfText = objReader.ReadLine 'stores seperate lines of data in HockeyFile into LineofText
aryTextFile = LineOfText.Split(",") 'takes lines and converts data into array
Name = aryTextFile(0) 'first piece of data in lines of text is the name
nameText(i) = aryTextFile(0)
If nameText(0) = "Name" Then
TextBox1.Text = LineOfText & ", Points." & vbCrLf 'displays first line fo text and adds "Points" label
End If
If Name <> "Name" Then 'when second line starts, then begin to intepret data
NumberText(i) = aryTextFile(1)
assistsText(i) = aryTextFile(2) 'assists are in third value of array
goalsText(i) = aryTextFile(3) 'goals are in fourth value of array
GamesWonText(i) = aryTextFile(4)
IntAssists(i) = Val(assistsText(i)) 'since our assists value is a string by default, it must be converted to a integer
IntGoals(i) = Val(goalsText(i)) 'since our goals value is a string by default, it must be converted to a integer
PointsText(i) = (IntGoals(i) * 2) + (IntAssists(i)) 'goals are two points, assists are one point
TextBox1.Text = TextBox1.Text & NumberText(i) & assistsText(i) & goalsText(i) & GamesWonText(i) & PointsText(i) & vbCrLf 'Displays points as last value in each line
End If
Next i
This should get you pretty close:
It'll need extra validation. It doesn't take into account whatever value you have between the name and the goals.
Private Sub ProcessHockeyStats()
Try
Dim inputFile As String = "c:\temp\hockey.txt"
Dim outputFile As String = "c:\temp\output.txt"
If Not File.Exists(inputFile) Then
MessageBox.Show("Missing input file")
Return
End If
If File.Exists(outputFile) Then
File.Delete(outputFile)
End If
Dim lines() As String = File.ReadAllLines(inputFile)
Dim output As List(Of String) = New List(Of String)
Dim firstLine As Boolean = True
For Each line As String In lines
Dim values() As String = line.Split(","c)
Dim points As Integer
If firstLine Then
output.Add("Name, Assists, Goals, Points")
firstLine = False
Else
'needs validation for values
points = CInt(values(1) * 2) + CInt(values(2))
output.Add(String.Concat(line, ",", points))
End If
Next
File.WriteAllLines("c:\temp\outfile.txt", output)
Catch ex As Exception
MessageBox.Show(String.Concat("Error occurred: ", ex.Message))
End Try
End Sub
VS2008 is ancient, especially when later versions of Visual Studio are free. I felt like showing an implementation using more-recent code. Like others, I strongly support building a class for this. The difference is my class is a little smarter, using the Factory pattern for creating instances and a Property to compute Points as needed:
Public Class HockeyPlayer
Public Property Name As String
Public Property Number As String
Public Property Assists As Integer
Public Property Goals As Integer
Public Property Wins As Integer
Public ReadOnly Property Points As Integer
Get
Return (Goals * 2) + Assists
End Get
End Property
Public Shared Function FromCSVLine(line As String) As HockeyPlayer
Dim parts() As String = line.Split(",")
Return New HockeyPlayer With {
.Name = parts(0),
.Number = parts(1),
.Assists = CInt(parts(2)),
.Goals = CInt(parts(3)),
.Wins = CInt(parts(4))
}
End Function
End Class
Dim hockeyFile As String = "C:\Users\Bob\Downloads\hockey.txt"
Dim players = File.ReadLines(hockeyFile).Skip(1).
Select(Function(line) HockeyPlayer.FromCSVLine(line)).
ToList() 'ToList() is optional, but I included it since you asked about an array
Dim result As New StringBuilder("Name, Number, Assists, Goals, Wins, Points")
For Each player In players
result.AppendLine($"{player.Name}, {player.Number}, {player.Assists}, {player.Goals}, {player.Wins}, {player.Points}")
Next player
TextBox1.Text = result.ToString()
I was gonna give you VS 2008 version afterward, but looking at this, the only thing here you couldn't do already even by VS 2010 was string interpolation... you really should upgrade.
Parallel arrays are really not the way to handle this. Create a class or structure to organize the data. Then create a list of the class. The list can be set as the DataSource of a DataGridView which will display your data in nice columns with headings matching the names of your properties in the Hockey class. You can easily order your data in the HockeyList by any of the properties of Hockey.
Public Class Hockey
Public Property Name As String
Public Property Number As String
Public Property Goals As Integer
Public Property Assists As Integer
Public Property Points As Integer
Public Property GamesWon As Integer
End Class
Private HockeyList As New List(Of Hockey)
Private Sub FillListAndDisplay()
Dim path = "C:\Users\Bob\Downloads\hockey.txt"
Dim Lines() = File.ReadAllLines(path)
For Each line As String In Lines
Dim arr() = line.Split(","c)
Dim h As New Hockey()
h.Name = arr(0)
h.Number = arr(1)
h.Assists = CInt(arr(2).Trim)
h.Goals = CInt(arr(3).Trim)
h.GamesWon = CInt(arr(4).Trim)
h.Points = h.Goals * 2 + h.Assists
HockeyList.Add(h)
Next
Dim orderedList = (From scorer In HockeyList Order By scorer.Points Ascending Select scorer).ToList
DataGridView1.DataSource = orderedList
End Sub

Adding Regex matches to an array

I'm struggling to solve a small bit of code. What the code does is to first load a CSV file, line by line (starting by line 3), and add it to an array. Then run a regex match and I want to insert the value in an array.
This is my working code, it shows a msgbox with the actual matches:
Dim file = "C:\Users\David\Desktop\mycsv.csv"
Dim basestatisticspath = Path.GetDirectoryName(file)
Dim statistics() As String = IO.File.ReadAllLines(file)
'Dim x As Integer = statistics.Length
'ReDim Preserve statistics(x)
Dim regexlang As Regex = New Regex("(?<=^"")\[.*\]")
Dim regexlinefilename As Regex = New Regex("(?<=^""\[.*?\]\s).*(?="")")
Dim linefilename As Match = Nothing
Dim langmatch As Match = Nothing
Dim filename() As String
Dim lang() As String
For i = 2 To UBound(statistics)
langmatch = regexlang.Match(statistics(i))
linefilename = regexlinefilename.Match(statistics(i))
MsgBox(langmatch.Value & linefilename.Value)
Next
That works well and the actual matches is what I want. So my next step was to add each match to an array to then use it to generate other files.
Therefore I ended up with this:
Dim file = "C:\Users\David\Desktop\myscv.csv"
Dim basestatisticspath = Path.GetDirectoryName(file)
Dim statistics() As String = IO.File.ReadAllLines(file)
'Dim x As Integer = statistics.Length
'ReDim Preserve statistics(x)
Dim regexlang As Regex = New Regex("(?<=^"")\[.*\]")
Dim regexlinefilename As Regex = New Regex("(?<=^""\[.*?\]\s).*(?="")")
Dim linefilename As Match = Nothing
Dim langmatch As Match = Nothing
Dim filename() As String
Dim lang() As String
' Set all value line by line
For i = 2 To UBound(statistics)
langmatch = regexlang.Match(statistics(i))
linefilename = regexlinefilename.Match(statistics(i))
lang(i) = langmatch.Value.ToString
filename(i) = linefilename.Value.ToString
MsgBox(langmatch.Value & linefilename.Value)
Next
After adding the below the program crashes on that line
lang(i) = langmatch.Value.ToString
filename(i) = linefilename.Value.ToString
I am assuming you can add the value of a regex match to a certain position of a string, but it seems I am wrong.
I´ve been searching for an answer with no results (at least to my poor understanding).
How could I convert each of the matches to a string and add it to the i position of the array?
Thanks in advance!
UPDATE:
As #Tval explained, I solved it by including the size of the array when declaring it. Thanks!
Dim filename(UBound(statistics)) As String
Dim lang(UBound(statistics)) As String
you need to initialize the array before you can reference it or you'll get a null reference error, also you can't reference an index that doesn't exist yet or you'll get an index out of range exception.
right now your using an array with a fixed length, so if you want to add a value to it you'll have to re-declare it one index larger every time.
If you want an array of a variable length id suggest using a list, so you can just append values to it without any issues
Dim myList = New List(Of String)
For Each foo As String In bar
myList.Add(bar)
Next

How to create find/replace add in with two multiline textboxes

I'm trying to create a find and replace macro for use as an add-in. I'd like to do so with a userform containing two multiline textboxes where users can enter the strings they would like to find and replace. I've figured out how to put these strings into arrays, but cannot figure out how to match the 'find' array with the 'replace' array and run a Replace command.
Is there some way to give each entry in each array a value, and match them up? I.e. the first string in the 'find' textbox gets a value of 1, the second gets a value of 2, and the same for the 'replace' textbox. Then the macro replaces any instances of 'find' string value 1 with 'replace' string value 1, and so on.
Here's the code I've figured out so far, thanks in advance for the help.
Private Sub CommandButton1_Click()
Dim Find_text As String
Dim Replace_text As String
Dim Find_lines As Variant
Dim x As Integer
Dim Replace_Lines As Variant
Dim y As Integer
Dim find As String
Dim Replace2 As String
Find_text = Find1.Text
Replace_text = Replace1.Text
Find_lines = Split(FindReplace2.Find1, vbCrLf)
Replace_Lines = Split(FindReplace2.Replace1, vbCrLf)
For x = LBound(Find_lines) To UBound(Find_lines)
find = Find_lines(x)
For y = LBound(Replace_Lines) To UBound(Replace_Lines)
Replace2 = Replace_Lines(y)
Next y
Next x
End Sub

Visual Basic: How to get entire section before/after a certain character?

I have a string. For example stringone/string2
How do I get the section before the "/" and also after the "/"
Dim Word As String = "stringone/string2"
Dim wordArr As String() = Word.Split("/")
Dim stringBefore As String = wordArr(???)
Dim stringBefore As String = wordArr(???)
What is the next step
Split() returns an Array. The first element is at Index 0 (zero), the second element is at Index 1 (one), etc...
You should check to make sure the returned array is your expected size (at least), otherwise you'll get an error attempting to access an index slot that doesn't exist.
Dim Word As String = "stringone/string2"
Dim wordArr As String() = Word.Split("/")
If wordArr.Length = 2 Then
Dim stringBefore As String = wordArr(0)
Dim stringAfter As String = wordArr(1)
Debug.Print("stringBefore = " & stringBefore)
Debug.Print("stringAfter = " & stringAfter)
End If
*By the way, the code you posted is not VB6, it's VB.Net.

Resources