Making new object from custom class- name using a variable value? - vb.net

I am making a LIST to organize and manipulate arrays that represent lines off a spreadsheet. I've created a custom class for the arrays, and will call them out as objects.
My question is, can I use a value stored in a variable as the name of the object? If so, what would the syntax look like?
dim FileName as String
FileName = 123456.csv
Public Class List_Array
public variable1 as string
public variable2 as string
public variable3 as string
public variable4 as string
End Class
dim File_Name as List_Array = NEW List_Array
This is the coding as I understand it, but I keep thinking this will only create one Object over and over again with the same name as the string variable.
If not, how can I differentiate the different objects as I call them? There will be thousands of objects to reference, so using an unnamed object will not work so well.

If you want to store a list of named objects, what you need is a Dictionary. Dictionary objects store a list of key/value pairs. In this case, the "key" is the name that you want to assign to the object, and the value is the reference to the object itself. It's a generic class, which means when you use the Dictionary type, you must specify the types that you want it to use for it's keys and values. For instance Dictionary(Of String, MyClass) will create a list that uses String objects for its keys and MyClass objects for its values.
Here's an example of how you could use a dictionary to store a list of people with their ages:
Dim d As New Dictionary(Of String, Integer)()
d("Bob") = 30
d("Mary") = 42
Then, when you want to read a value, you can do it like this:
Dim age As Integer = d("Bob")
The Dictionary will only allow one item per key. It uses a hash table to index the values by their keys, so it's very fast get any item by its key.
Edit
Based on your comments below, here's a more pertinent example to show what I mean. Let's say you have a CSV file containing a list of people. So you create a class that stores all of the information about one person (one line of the CSV file), like this:
Public Class Person
Public Property Id As String
Public Property Name As String
Public Property Title As String
End Class
Then, you create a method which parses a single line from the CSV file and returns all of the fields from that line as an array of strings, like this:
Public Function ParseCsvLine(line As String) As String()
' ...
End Function
Then, you could load all of the people into a list, like this:
Dim persons As New List(Of Person)()
For Each line As String In File.ReadAllLines("People.csv")
Dim fields() As String = ParseCsvLine(line)
Dim person As New Person()
person.Id = fields(0)
person.Name = fields(1)
person.Title = fields(2)
persons.Add(person)
Next
Now you have all of the Person objects loaded into one list. The problem is, though, that the list is not indexed. If, for instance, you needed to find the person with an ID of 100, you'd need to loop through all of the Person objects in the list until you found one with that value in it's Id property. If you want to index them by ID so that you can find them more easily/quickly, you can use a Dictionary, like this:
Dim persons As New Dictionary(Of String, Person)()
For Each line As String In File.ReadAllLines("People.csv")
Dim fields() As String = ParseCsvLine(line)
Dim person As New Person()
person.Id = fields(0)
person.Name = fields(1)
person.Title = fields(2)
persons(person.Id) = person
Next
Then, when you need to get a person from the dictionary, you can easily access it by ID, like this:
Dim person100 As Person = persons("100")

Related

extract list of string from list of custom class

i have a list(of custom class)
and i want to extract a list of all 'name' String, from it, through linq
I know how to do with a loop, but i need to get it with a linear, brief linq instruction.
i've checked this help
C# Extract list of fields from list of class
but i have problem in linq correct syntax
in particular because i would like to extract a New List(Of String)
Class Student
Sub New(ByVal NewName As String, ByVal NewAge As Integer)
Name = NewName
Age = NewAge
End Sub
Public Name As String
Public Age As Integer
End Class
Public Sub Main
Dim ClassRoom as New List(Of Student) From {New Student("Foo",33), New Student("Foo2",33), New Student("Foo3",22)}
Dim OneStudent as Student = ClassRoom(0)
Dim AllStudentsNames As New List(Of String) From {ClassRoom.Select(Function(x) x.Name <> OneStudent.Name).ToList}
End Sub
But something wrong...
Any help?
P.S. Since c# it's close to vb.Net, also c# helps are well welcome.
First, you don't need to create a new list From the one returned by the LINQ method. It's already in a new list at that point, so you can just set AllStudentsNames equal directly to what the ToList method returns.
Second, you are not selecting the name. You are selecting the result of the equality test to see if the names are different. In other words, when you say Select(Function(x) x.Name <> OneStudent.Name), that returns a list of booleans, where they true if the names are different and false if the names are the same. That's not what you want. You want the list of names, so you need to select the name.
Third, if you need to filter the list so that it only returns ones where the name is different, then you need to add a call to the Where method.
Dim AllStudentsNames As List(Of String) = ClassRoom.
Where(Function(x) x.Name <> OneStudent.Name).
Select(Function(x) x.Name).
ToList()

Get data from a collection

I want to make a collection to have data available
Example:
Dim b As New Collection
colb = New Collection
b.Add("system", "1001", "SYSTEM")
b.Add("network", "1002", "NETWORKA")
b.Add("networksecond", "1010", "NETWORKB")
colb.Add(b, "list")
im looking for a function to get data from this collection:
I want to, based on the ID (Second number) get the first and third value
So if I search for 1010, I need to have the value Network and NETWORKA
VB6 called, they want their Collection back.
No, seriously, please consider using a Dictionary instead of the old, legacy Collection class. Behold the beauty of generics and strong typing:
Dim dic As New Dictionary(Of Integer, Tuple(Of String, String))
dic.Add(1001, Tuple.Create("system", "SYSTEM"))
dic.Add(1002, Tuple.Create("network", "NETWORKA"))
dic.Add(1010, Tuple.Create("networksecond", "NETWORKB"))
' Search
Dim t As Tuple(Of String, String) = Nothing
If dic.TryGetValue(1002, t) Then
Console.WriteLine(t.Item1) ' prints "network"
Console.WriteLine(t.Item2) ' prints "NETWORKA"
End If
As soon as you have more than two values, I suggest that you use a specialized class instead of a Tuple to increase readability.
Also, you can simply use List(Of T). In most cases this is enough. Dictionary is good for fast search out long list by a single key.
'declare model
Public Class NetworkModel
Public Property Id As Integer
Public Property Name1 As String
Public Property Name2 As String
End Class
' load list of models
Private _modelList As New List(Of NetworkModel)()
.......
' search using LINQ
Dim model As NetworkModel = _modelList.FirstOrDefault(Function(m) m.Id = 1001)
If model IsNot Nothing Then . . . . .

VB.NET How would I store multiple inputs in a single preset structure

So I've been making a 'database' that would store different students ID's, names and grades.
And the problem I'm having is that the my structure has no 'depth' and I can only store one set of data inside it. How would I increase the capacity of my structure so I'm able to store more than 1 set of data? My code is this:
Structure record
Dim ID As Integer
Dim fname As String
Dim sName As String
Dim grade As String
End Structure
Convert your struct to a class:
Class clsRecord
public ID As Integer
public fname As String
public sName As String
public grade As String
end class
Create a List to hold a collection of Record Classes
Dim lstRecords as List(Of clsRecord)
Create new instance of class clsRecord
Dim someRecord as new clsRecord
Populate members
eg
someRecord.ID = 1
Add class to collection
lstRecord.Add(someRecord)
Repeat
Then loop through collection for each record
For Each xRecords in lstRecords
'do something
Next

Can I concatenate 2 columns in my query when using SELECT in ado.net?

VS2013, vb.net
For this class (only the relevant properties are displayed):
Public Class UserPost
Public Property Title As String
Public Property Topic As String
Public Property Type As ChannelType 'ChannelType is an Enum
End Class
The following query returns a simple list(of string) holding the titles of the UserPosts with Topic = topic:
Dim rtnList As New List(Of String)
rtnList = db.UserPost.Where(Function(x) x.Topic = topic).Select(Function(x) x.Anchor.Title).ToList()
But it would be useful to also report the ChannelType as a prefix to the Title. I could create a more complicated object to receive 2 columns and combine them later, but I wondered if there is a way to concatenate the columns in the query so that the rtnList receives the result of:
ChannelType.tostring() & Title
without having to code that afterword.
Of course there is. You just do pretty much exactly what you said. Instead of returning x.Anchor.Title you return x.Anchor.ChannelType.ToString() & x.Anchor.Title.

How do you assign values to structure elements in a List in VB.NET?

I have a user-defined structure in a list that I am trying to change the value for in an individual element within the list of structures. Accessing the element is not a problem. However, when I try to update the value, the compiler complains:
"Expression is a value and therefore cannot be the target of the
assignment"
For example:
Public Structure Person
Dim first as String
Dim last as String
Dim age as Integer
End Structure
_
Public Sub ListTest()
Dim newPerson as Person
Dim records as List (Of Person)
records = new List (Of Person)
person.first = "Yogi"
person.last = "bear"
person.age = 35
records.Add(person)
records(0).first = "Papa" ' <<== Causes the error
End Sub
As the other comments said, when you refer to records(0), you get a copy of the struct since it is a value type. What you can do (if you can't change it to a Class) is something like this:
Dim p As Person = records(0)
p.first = "Papa"
records(0) = p
Although, I think it's just easier to use a Class.
There are actually two important concepts to remember here.
One is that, as Hans and Chris have pointed out, Structure Person declares a value type of which copies are passed between method calls.
You can still access (i.e., get and set) the members of a value type, though. After all, this works:
Dim people(0) As Person
people(0).first = "Yogi"
people(0).last = "Bear"
people(0).age = 35
So the other important point to realize is that records(0) accesses the List(Of Person) class's special Item property, which is a sugary wrapper around two method calls (a getter and setter). It is not a direct array access; if it were (i.e., if records were an array), your original code would actually have worked.
I had the same problem, and I fixed it by adding a simple Sub to the structure that changes the value of the property.
Public Structure Person
Dim first as String
Dim last as String
Dim age as Integer
Public Sub ChangeFirst(value as String)
me.first = value
End Sub
End Structure