Collection to delimited string - vb.net

when I do
String.Join(";", lst.Items)
I get a string of object descriptors instead of item of values.
But when I iterate the collection, I end up with a delimiter at the front or back and need to a Substring call afterwards.
Dim res As String = "" 'or use stringbuilder
For Each s As String In lst.Items
s &= ";" & s
Next
res = res.Substring(1)
This applies to other cases as well where you want to turn a shared property within a collection into a delimited string. Is there a nice way to do this?
Can I do this with LINQ and would it be faster?

You'll have to convert the items to strings then:
String.Join(";", lst.Items.Select(Function(item) item.ToString()));

How about
Dim res As String = String.Join(";", lst.Items.OfType(Of String))

This does work:
Dim col As New Collection
col.Add("One")
col.Add("Two")
col.Add("Three")
Dim res = String.Join(";", col.OfType(Of String))
See also this question

Related

How to remove an element from a char array in VB.NET?

is there any way to remove the element in char array I converted from a String?
Dim myString As String = "Hello"
Dim charArray As Char() = myString.ToCharArray
Your help would be much appreciated.. Thanks
Arrays are fixed-length in .NET. You can set an element to Nothing but you cannot remove that element. You can use a collection instead of an array and then you can add, insert and remove items at will, but your example isn't necessarily the best case for that sort of thing, e.g.
Dim str = "Hello"
Dim chars = New List(Of Char)(str)
You can then call Remove or RemoveAt on that List to remove a Char. You can then create a new String if desired, e.g.
chars.RemoveAt(2)
str = New String(chars.ToArray())
Console.WriteLine(str)
That will display "Helo".

How to output data from Structure to CSV using StringBuilder

I have data in the following structure:
Structure student
Dim stdntpass As String
Dim fname As String
Dim sname As String
Dim age As Byte
Dim year As Integer
Dim stdntuser As String
End Structure
I need to take the data in that structure and output it to CSV. I was planning on using a StringBuilder object to do it, but I can't figure out how to give the structure to the StringBuilder.
Here is a function that uses reflection to determine what fields exist in the student structure:
Public Function StudentsToCSV(students As IEnumerable(Of student)) As String
Const separator As Char = ";"c
Dim sb As New StringBuilder
'Get the data elements
Dim studentFields = GetType(student).GetFields()
'Output headline (may be removed)
For Each field In studentFields
sb.Append(field.Name)
sb.Append(separator)
Next
sb.AppendLine("")
'Write a line for each student
For Each s In students
'Write the value of each field
For Each field In studentFields
Dim value As String = Convert.ToString(field.GetValue(s))
sb.Append(value)
'... followed by the separator
sb.Append(separator)
Next
sb.AppendLine("")
Next
Return sb.ToString()
End Function
You can pass any set of students to this function - may it be an array, a List(Of student) or whatever.
One way is to override the ToString function. now passing a whole object to a stringbuilder or even sending the Tostring function to the file will pass the values how you want them:
Structure student
Dim stdntpass As String
Dim fname As String
Dim sname As String
Dim age As Byte
Dim year As Integer
Dim stdntuser As String
Public Overrides Function ToString() As String
Return Join({stdntpass, fname, sname, age.ToString, year.ToString, stdntuser}, ","c) + vbNewLine
End Function
End Structure
The StringBuilder has no way to take a whole Structure and automatically append each of the properties from that Structure. If you must use a StringBuilder, you could do it like this:
builder.Append(s.stdntpass)
builder.Append(",")
builder.Append(s.fname)
builder.Append(",")
builder.Append(s.sname)
builder.Append(",")
builder.Append(s.age)
builder.Append(",")
builder.Append(s.year)
builder.Append(",")
builder.Append(s.stdntuser)
Dim csvLine As String = builder.ToString()
However, it would be easier to use the String.Join method, like this:
Dim csvLine As String = String.Join(",", s.stdntpass, s.fname, s.sname, s.age, s.year, s.stdntuser)
You could use reflection to dynamically get the list of properties from the structure, but then you won't have much control over the order in which the fields get appended without using attributes, or something, which could get ugly.
In any case, you should be careful, though, that values are properly escaped. If any of the strings in your structure contain commas, you need to surround that field with quotation marks. And if any of those strings quotation marks, they need to be doubled. You could fix the values with a method like this:
Public Function EscapeValueForCsv(value As String) As String
Return """" & value.Replace("""", """""") & """"
End Function
Then you could call that on each of the properties before passing it to String.Join:
Dim csvLine As String = String.Join _
(
",",
EscapeValueForCsv(s.stdntpass),
EscapeValueForCsv(s.fname),
EscapeValueForCsv(s.sname),
EscapeValueForCsv(s.age.ToString()),
EscapeValueForCsv(s.year.ToString()),
EscapeValueForCsv(s.stdntuser)
)

String.Split Method optimize way in vb.net

I have a string xxx1-0.1/1 yyy,ccc1,1. I used split and substring. All i want to get is the 0.1/1 only. Is there any optimize way to do this?
Thank you in advance!
Use more than one string split chars. then if the position and format is always the same then this will work.
Dim s As String = "xxx1-0.1/1 yyy,ccc1,1"
Dim ans = s.Split(New Char() {"-"c, " "c})(1)
MessageBox.Show(ans)
Lets make it a function:
Private Function getMySpecialValue(input As String) As String
Return input.Split(New Char() {"-"c, " "c})(1)
End Function

iterating a list with ForEach

I have a list like this
Dim emailList as new List(Of String)
emailList.Add("one#domain.com")
emailList.Add("two#domain.com")
emaillist.Add("three#domain.com")
How can I iterate the list with ForEach to get one string with the emails like this
one#domain.com;two#domain.com;three#domain.com
I'm not sure why you would want to use a foreach instead of a String.Join statement. You could simply String.Join() the list using a semi-colon as your joining character.
String.Join(";", emailList.ToArray())
You can try
Dim stringValue As String = String.Join(";", emailList.ToArray)
Have a look at String.Join Method
I wouldn't actually use a ForEach loop for this. Here is what I would do:
String.Join(";", emailList.ToArray());
Dim emailList As New List(Of String)
emailList.Add("one#domain.com")
emailList.Add("two#domain.com")
emailList.Add("three#domain.com")
Dim output As StringBuilder = New StringBuilder
For Each Email As String In emailList
output.Append(IIf(String.IsNullOrEmpty(output.ToString), "", ";") & Email)
Next
Dim emailList As New StringBuilder()
For Each (email As String In emails)
emailList.Append(String.Format("{0};", email))
Next
Return emailList.ToString()
Forgive me if there are any syntax errors ... my VB.NET is a little rusty and I don't have a complier handy.

String Array Thing!

Right - to start with, I'm entering unfamiliar areas with this - so please be kind!
I have a script that looks a little something like this:
Private Function checkString(ByVal strIn As String) As String
Dim astrWords As String() = New String() {"bak", "log", "dfd"}
Dim strOut As String = ""
Dim strWord As String
For Each strWord In astrWords
If strIn.ToLower.IndexOf(strWord.ToLower, 0) >= 0 Then
strOut = strWord.ToLower
Exit For
End If
Next
Return strOut
End Function
It's function is to check the input string and see if any of those 'astrWords' are in there and then return the value.
So I wrote a bit of code to dynamically create those words that goes something like this:
Dim extensionArray As String = ""
Dim count As Integer = 0
For Each item In lstExtentions.Items
If count = 0 Then
extensionArray = extensionArray & """." & item & """"
Else
extensionArray = extensionArray & ", ""." & item & """"
End If
count = count + 1
Next
My.Settings.extensionArray = extensionArray
My.Settings.Save()
Obviously - it's creating that same array using list items. The output of that code is exactly the same as if I hard coded it - but when I change the first bit of code to:
Dim astrWords As String() = New String() {My.Settings.extensionArray}
instead of:
Dim astrWords As String() = New String() {"bak", "log", "dfd"}
It starts looking for the whole statement instead of looping through each individual one?
I think it has something to do with having brackets on the end of the word string - but I'm lost!
Any help appreciated :)
When you use the string from the settings in the literal array, it's just as if you used a single strings containing the delimited strings:
Dim astrWords As String() = New String() {"""bak"", ""log"", ""dfd"""}
What you probably want to do is to put a comma separated string like "bak,log,dfd" in the settings, then you can split it to get it as an array:
Dim astrWords As String() = My.Settings.extensionArray.Split(","C)
You need to set extensionArray up as a string array instead of simply a string.
Note that
Dim something as String
... defines a single string, but
Dim somethingElse as String()
... defines a whole array of strings.
I think with your code, you need something like:
Dim extensionArray As String() = new String(lstExtensions.Items)
Dim count As Integer = 0
For Each item In lstExtentions.Items
extensionArray(count) = item
count = count + 1
Next
My.Settings.extensionArray = extensionArray
My.Settings.Save()
Then at the start of checkString you need something like
Private Function checkString(ByVal strIn As String) As String
Dim astrWords As String() = My.Settings.extensionArray
...
There also might be an even easier way to turn lstExtentions.Items into an Array if Items has a 'ToArray()' method, but I'm not sure what Type you are using there...
What you've done is created a single string containing all 3 words. You need to create an array of strings.
New String() {"bak", "log", "dfd"}
means create a new array of strings containing the 3 strings values "bak", "log" and "dfd".
New String() {My.Settings.extensionArray}
means create a new array of strings containing just one value which is the contents of extensionArray. (Which you have set to ""bak", "log", "dfd""). Note this is one string, not an array of strings. You can't just create 1 string with commas in it, you need to create an array of strings.
If you want to create your array dynamically, you need to define it like this:
Dim astrWords As String() = New String(3)
This creates an array with 3 empty spaces.
You can then assign a string to each space by doing this:
astrWords(0) = "bak"
astrWords(1) = "log"
astrWords(2) = "dfd"
You could do that bit in a for loop:
Dim count As Integer = 0
For Each item In lstExtentions.Items
astrWords(count) = item
count = count + 1
Next
Alternatively, you could look at using a generic collection. That way you could use the Add() method to add multiple strings to it
I think you want your extensionArray to be of type String() and not String. When you are trying to initialize the new array, the initializer doesn't know to parse out multiple values. It just sees your single string.