3

I've got two strings that I want to associate together so that I can search by username and get the computername. Strings: username computername

I'm not that fluent in VB code so I don't know how to build this object. This is what I think I need:

(
  ("user1" "computer1")
  ("user2" "computer2")
  ("user3" "computer3")
  ("user4" "computer4")
  ("user5" "computer5")
)

Then I want to be able to query the list by asking: What computername is associated with "user3"? And get "computer3" as the result.

vcsjones
  • 138,677
  • 31
  • 291
  • 286

5 Answers5

4

You're looking for a System.Collections.Generic.Dictionary. Specifically a Dictionary(Of String, String).

Add items one at a time:

Dim computers As New Dictionary(Of String, String)
computers.Add("user1", "computer1")
computers.Add("user2", "computer2")
'...

Or, you can use an initializer and do it in one fell swoop:

Dim computers As New Dictionary(Of String, String) From
    {
      {"user1" "computer1"},
      {"user2" "computer2"},
      {"user3" "computer3"},
      {"user4" "computer4"},
      {"user5" "computer5"}
    }

And access individual elements using an indexer:

Dim result As String = computers("user3")

Note this will throw an exception if "user3" does not exist in the collection. You may wish to look into TryGetValue if there is a possibility to search for nonexistent keys.

lc.
  • 113,939
  • 20
  • 158
  • 187
1

While the answers using dictionary will surely work, I personally prefer to use a class and and list.

You'd do something like this:

Public Class UserComputer
    Private _user As String
    Public Property User() As String
        Get
            Return _user
        End Get
        Set(ByVal value As String)
            _user = value
        End Set
    End Property

    Private _comp As String
    Public Property Computer() As String
        Get
            Return _comp
        End Get
        Set(ByVal value As String)
            _comp = value
        End Set
    End Property

    Public Sub New(User As String, Computer As String)
      Me.User = User
      Me.Computer = Computer
    End Sub

End Class

Public Sub Main()
  Dim myList As New List(Of UserComputer)
  myList.Add(New UserComputer("user1", "computer1")
  '... keep adding objects
End Sub

The advantage here is that it becomes very easy to extend your class UserComputer should you need to; just add more properties to the class. It also let's you easily consume the information in the objects in other parts of your program.

Seth
  • 199
  • 9
1

I suppose there is the possibility that one computer is used by more than one user, and more than one user could use a particular computer. In that case, it is probably going to be simpler to have a class which holds the information relating a user to a computer. You can then make a List of instances of that class to hold the entire set of information, and being a List, you can easily query it with LINQ, like this:

Option Infer On
Module Module1

    Dim computerUsers As New List(Of ComputerUser)

    Class ComputerUser
        Property ComputerName As String
        Property UserName As String
    End Class

    Sub CreateTestData()
        computerUsers = New List(Of ComputerUser)
        computerUsers.Add(New ComputerUser With {.ComputerName = "PC1", .UserName = "Fred"})
        computerUsers.Add(New ComputerUser With {.ComputerName = "PC2", .UserName = "Jim"})
        computerUsers.Add(New ComputerUser With {.ComputerName = "PC3", .UserName = "Jane"})
        computerUsers.Add(New ComputerUser With {.ComputerName = "PC1", .UserName = "Jim"})

    End Sub

    Sub Main()
        CreateTestData()

        Dim pcName = "PC1"
        Dim thisPcUsers = computerUsers.Where(Function(x) x.ComputerName = pcName).Select(Function(y) y.UserName).ToList()
        Console.WriteLine(pcName & " is used by: " & String.Join(", ", thisPcUsers))

        Dim user = "Jim"
        Dim thisUserPCs = computerUsers.Where(Function(x) x.UserName = user).Select(Function(y) y.ComputerName).ToList()
        Console.WriteLine(user & " uses computers: " & String.Join(", ", thisUserPCs))

        Console.ReadLine()

    End Sub

End Module

Which outputs

PC1 is used by: Fred, Jim
Jim uses computers: PC2, PC1

Edit +1 to Seth, whose answer I did not see while I was writing this.

Edit 2 You can use LINQ in various ways, for example to get the users whose names start with "J*":

Dim partialName = "J*"
Dim usersWithWildcard = computerUsers.Where(Function(x) x.UserName Like partialName).ToList()

Console.WriteLine("Users starting with " & partialName)
For Each u In usersWithWildcard
    Console.WriteLine(u.UserName)
Next
Andrew Morton
  • 24,203
  • 9
  • 60
  • 84
  • I have got the code working and have computerUsers and thisUserPCs. How do I test to see if a user is even in computerUsers? How would I pump the String.Join(", ", thisUserPCs) into a listbox? I'm even wondering how to verify a user exists in computerUsers with a wildcard (start typing br... and it will filter to all of the users that start with br*) – bowlingbrad Nov 01 '13 at 19:21
  • For example: the form loads and finds all of the computers that match the user * (all of them). It fills the list box with the list of computers. A user starts typing in the username text box and the computer list begins to filter down as they type. – bowlingbrad Nov 01 '13 at 19:26
  • @bowlingbrad I've edited my answer to include an example of using VB's `Like` with a wildcard. You should attempt to learn about LINQ. – Andrew Morton Nov 01 '13 at 20:23
0

I suspect that want you want is a Dictionary(Of String, String):

Dim x as New Dictionary(Of String, String)
x.Add("user1", "computer1") ' etc...

Dim computer as String = x("user1")
Dan Puzey
  • 33,626
  • 4
  • 73
  • 96
  • Now, how do I trap for an error? Say x("user6") returns an error. – bowlingbrad Oct 23 '13 at 15:05
  • You can use the `.ContainsKey` method to see whether `"user6"` exists, or you can use `TryGetValue` to get the value - which uses a `ByRef` parameter and will return `false` if there's no matching key. – Dan Puzey Oct 23 '13 at 15:15
  • I don't know if I'm using these correctly. I put in x("user6").ContainsKey or x("user6").TryGetValue and vs2010 isn't recognizing them. – bowlingbrad Oct 23 '13 at 15:24
  • 1
    You just need `x.ContainsKey("user6")` - or for `TryGetValue` you declare a variable for the output and use `x.TryGetValue("user6", computerName)`, which will return `True` if the value existed. – Dan Puzey Oct 23 '13 at 15:26
  • Here's another question... What if a user has two computers associated with him? What will x("user2") return if there are two entries with this username? – bowlingbrad Oct 23 '13 at 16:03
  • I just tested it and found that you cannot have more than one "user2". Is there a way to do this? Can I add a third value to the dictionary array? Maybe Dictionary(Of Integer, String, String)? – bowlingbrad Oct 23 '13 at 16:08
  • 2
    @bowlingbrad You can have a `Dictionary(Of String, List(Of String)`. – Andrew Morton Oct 23 '13 at 17:28
0
Dim userComputers As New Dictionary(Of String, String) From
{   
   {"user1" "computer1"},
   {"user2" "computer2"},
   {"user3" "computer3"},
   {"user4" "computer4"},
   {"user5" "computer5"}
}

Dim computer As String = userComputers("user3")
Joel Coehoorn
  • 399,467
  • 113
  • 570
  • 794