Results 1 to 6 of 6

Thread: Dictionary, more than one item

  1. #1

    Thread Starter
    Hyperactive Member
    Join Date
    Apr 2010
    Posts
    402

    Dictionary, more than one item

    Ok, I have tonight learnt how to use the dictionary function, which is really grate. However from what I can see you can only have two items per entry, The key and the returned value. Is there a similar function that I can use as a lookup table which will return more than one returned value. Or is it a case of having the returned value a class that contains multiple items?

  2. #2
    eXtreme Programmer .paul.'s Avatar
    Join Date
    May 2007
    Location
    Chelmsford UK
    Posts
    25,464

    Re: Dictionary, more than one item

    An Array as your returned item, or a List(Of T) as your returned item???

  3. #3
    Smooth Moperator techgnome's Avatar
    Join Date
    May 2002
    Posts
    34,532

    Re: Dictionary, more than one item

    Would Tuples work?

    -tg
    * I don't respond to private (PM) requests for help. It's not conducive to the general learning of others.*
    * I also don't respond to friend requests. Save a few bits and don't bother. I'll just end up rejecting anyways.*
    * How to get EFFECTIVE help: The Hitchhiker's Guide to Getting Help at VBF - Removing eels from your hovercraft *
    * How to Use Parameters * Create Disconnected ADO Recordset Clones * Set your VB6 ActiveX Compatibility * Get rid of those pesky VB Line Numbers * I swear I saved my data, where'd it run off to??? *

  4. #4
    Angel of Code Niya's Avatar
    Join Date
    Nov 2011
    Posts
    8,598

    Re: Dictionary, more than one item

    A Dictionary is meant to be used for fast lookups. You should think of it like an array except you get to assign a key to each entry. If you need multiple values per entry, you do it the same as you would if it were an array, using a class, structure or as suggested above, perhaps even a Tuple.
    Treeview with NodeAdded/NodesRemoved events | BlinkLabel control | Calculate Permutations | Object Enums | ComboBox with centered items | .Net Internals article(not mine) | Wizard Control | Understanding Multi-Threading | Simple file compression | Demon Arena

    Copy/move files using Windows Shell | I'm not wanted

    C++ programmers will dismiss you as a cretinous simpleton for your inability to keep track of pointers chained 6 levels deep and Java programmers will pillory you for buying into the evils of Microsoft. Meanwhile C# programmers will get paid just a little bit more than you for writing exactly the same code and VB6 programmers will continue to whitter on about "footprints". - FunkyDexter

    There's just no reason to use garbage like InputBox. - jmcilhinney

    The threads I start are Niya and Olaf free zones. No arguing about the benefits of VB6 over .NET here please. Happiness must reign. - yereverluvinuncleber

  5. #5
    Super Moderator dday9's Avatar
    Join Date
    Mar 2011
    Location
    South Louisiana
    Posts
    11,715

    Re: Dictionary, more than one item

    Let's assume that you have the following schema:
    Code:
    CREATE TABLE LookupTable(
      LookupTableId INT NOT NULL AUTO_INCREMENT,
      LookupTableName VARCHAR(32) NOT NULL,
      Slug VARCHAR(32) NOT NULL,
      CONSTRAINT PK_LookupTable_LookupTableId PRIMARY KEY (LookupTableId),
      CONSTRAINT UC_LookupTable_LookupTableName UNIQUE (LookupTableName),
      CONSTRAINT UC_LookupTable_Slug UNIQUE (Slug)
    );
    
    INSERT INTO LookupTable (LookupTableName, Slug) VALUES
      ('Lookup 1', 'lookup_1'),
      ('Lookup 2', 'lookup_2'),
      ('Lookup 3', 'lookup_3');
    Fiddle: http://sqlfiddle.com/#!9/217e88/1

    Now you want to represent this table in Visual Basic .NET. One option that you have is to create a POCO object that is essentially a class with 3 properties representing your 3 fields:
    Code:
    Public Class LookupTable
    
        Private _lookupTableId As Integer
        Public Property LookupTableId As Integer
            Get
                Return _lookupTableId
            End Get
            Set (value As Integer)
                If (_lookupTableId <> value) Then
                    _lookupTableId = value
                    OnLookupTableIdChanged()
                End If
            End Set
        End Property
    
        Protected Overridable Sub OnLookupTableIdChanged()
            RaiseEvent LookupTableIdChanged(Me, EventArgs.Empty)
        End Sub
        
        Public Event LookupTableIdChanged(sender As Object, e As EventArgs)
    
        Private _lookupTableName As String
        Public Property LookupTableName As String
            Get
                Return _lookupTableName
            End Get
            Set (value As String)
                If (_lookupTableName <> value) Then
                    _lookupTableName = value
                    OnLookupTableNameChanged()
                End If
            End Set
        End Property
    
        Protected Overridable Sub OnLookupTableNameChanged()
            RaiseEvent LookupTableNameChanged(Me, EventArgs.Empty)
        End Sub
        
        Public Event LookupTableNameChanged(sender As Object, e As EventArgs)
    
        Private _lookupTableSlug As String
        Public Property LookupTableSlug As String
            Get
                Return _lookupTableSlug
            End Get
            Set (value As String)
                If (_lookupTableSlug <> value) Then
                    _lookupTableSlug = value
                    OnLookupTableSlugChanged()
                End If
            End Set
        End Property
    
        Protected Overridable Sub OnLookupTableSlugChanged()
            RaiseEvent LookupTableSlugChanged(Me, EventArgs.Empty)
        End Sub
        
        Public Event LookupTableSlugChanged(sender As Object, e As EventArgs)
    
    End Class
    To store data you would create new instances of the class and add them to a List(Of T):
    Code:
    Dim database As New List(Of LookupTable)({
        New LookupTable() With { .LookupTableId = 1, .LookupTableName = "Lookup 1", .LookupTableSlug = "lookup_1" },
        New LookupTable() With { .LookupTableId = 2, .LookupTableName = "Lookup 2", .LookupTableSlug = "lookup_2" },
        New LookupTable() With { .LookupTableId = 3, .LookupTableName = "Lookup 3", .LookupTableSlug = "lookup_3" }
    })
    Now when you want to query them you could use LINQ. For example, here is how to get the record with an Id of 1:
    Code:
    Dim lookup1 As LookupTable = database.Single(Function(record) record.LookupTableId = 1)
    Here is how you'd get all records where the Id is greater than 1:
    Code:
    Dim lookups As IEnumerable(Of LookupTable) = database.Where(Function(record) record.LookupTableId > 1)
    And so on...
    "Code is like humor. When you have to explain it, it is bad." - Cory House
    VbLessons | Code Tags | Sword of Fury - Jameram

  6. #6
    Karen Payne MVP kareninstructor's Avatar
    Join Date
    Jun 2008
    Location
    Oregon
    Posts
    6,684

    Re: Dictionary, more than one item

    For learning, another option is Lookup<TKey,TElement>

    In the following code written many years ago focus on Demo_3b while there are other examples which can be considered.

    Code:
    Public Class Product
        Public Property ID As Int32
        Public Property Category As String
        Public Property Value As Double
        Public Overrides Function ToString() As String
            Return $"{ID,3:D2}: {Category} - {Value:C} "
        End Function
    End Class
    Example code with mocked data

    Code:
    Module Operations
        Public Function Products() As List(Of Product)
    
            Return New List(Of Product) From
                {
                    New Product With {.ID = 1, .Category = "Electronics", .Value = 15.0},
                    New Product With {.ID = 2, .Category = "Groceries", .Value = 40.0},
                    New Product With {.ID = 3, .Category = "Garden", .Value = 210.3},
                    New Product With {.ID = 4, .Category = "Pets", .Value = 2.1},
                    New Product With {.ID = 5, .Category = "Electronics", .Value = 19.5},
                    New Product With {.ID = 6, .Category = "Pets", .Value = 21.25},
                    New Product With {.ID = 7, .Category = "Pets", .Value = 5.5},
                    New Product With {.ID = 8, .Category = "Garden", .Value = 13.0},
                    New Product With {.ID = 9, .Category = "Automotive", .Value = 10.0},
                    New Product With {.ID = 10, .Category = "Electronics", .Value = 250.0}
                }
    
        End Function
        Public Sub Demo_1()
            For Each group In Products.GroupBy(Function(p) p.Category)
    
                Console.WriteLine(group.Key)
    
                For Each item In group
                    Console.WriteLine("  {0}", item)
                Next
            Next
        End Sub
        Public Sub Demo_2()
    
            Dim groups As Dictionary(Of String, List(Of Product)) =
                    Products.GroupBy(Function(p) p.Category).ToDictionary(Function(g) g.Key, Function(g) g.ToList())
    
            For Each item In groups
                Console.WriteLine(item.Key)
                For Each p In item.Value
                    Console.WriteLine("  {0}", p)
                Next
            Next
    
        End Sub
        Public Sub Demo_3()
    
            Dim productsByCategory As ILookup(Of String, Product) =
                    Products.ToLookup(Function(p) p.Category)
    
            Dim Category = "Electronics"
    
            For Each product In productsByCategory(Category)
                Console.WriteLine(product)
            Next
    
        End Sub
        ' Nothing will display
        Public Sub Demo_3a()
            Dim productsByCategory = Products.ToLookup(Function(p) p.Category)
            Dim Category = "Whatever"
    
            For Each product In productsByCategory(Category)
                Console.WriteLine(product)
            Next
    
        End Sub
        Public Sub Demo_3b()
    
            Dim productsByCategory As ILookup(Of String, Product) = Products.ToLookup(Function(p) p.Category)
            Dim Category = "Electronics"
    
            Dim results As IEnumerable(Of IGrouping(Of String, Product)) =
                    productsByCategory.Where(Function(item) item.Key = Category)
    
            For Each products As IGrouping(Of String, Product) In results
                For Each product As Product In products
                    Console.WriteLine($"{product}")
                Next
            Next
        End Sub
        Public Sub Demo_4()
    
            Dim productIdsByCategory As ILookup(Of String, Integer) = Products.ToLookup(Function(p) p.Category, Function(p) p.ID)
    
            For Each item In productIdsByCategory
                Console.WriteLine(item.Key)
                For Each p In item
                    Console.WriteLine("  ID:{0}", p)
                Next
            Next
    
        End Sub
    End Module
    Call above code

    Module Module1

    Code:
        Sub Main()
            Console.WriteLine("Demo 1")
            Demo_1()
            Console.WriteLine()
    
            Console.WriteLine("Demo 2")
            Demo_2()
            Console.WriteLine()
    
            Console.WriteLine("Demo 3")
            Demo_3()
            Console.WriteLine()
    
            Console.WriteLine("Demo 3 a -- nothing will display")
            Demo_3a()
            Console.WriteLine()
    
            Console.WriteLine("3B WHere predicate")
            Demo_3b()
            Console.WriteLine()
    
            Console.WriteLine("Demo 4")
            Demo_4()
            Console.WriteLine()
            Console.ReadLine()
    
        End Sub
    
    End Module

    Where can we take this? Reading from a .json file or from two tables, in this case a category and product tables.

    For a bit of homework, one is mutable and one is immutable, read up on that.

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  



Click Here to Expand Forum to Full Width