-
Oct 20th, 2021, 07:37 PM
#1
Thread Starter
Hyperactive Member
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?
-
Oct 20th, 2021, 08:44 PM
#2
Re: Dictionary, more than one item
An Array as your returned item, or a List(Of T) as your returned item???
- Coding Examples:
- Features:
- Online Games:
- Compiled Games:
-
Oct 20th, 2021, 11:40 PM
#3
Re: Dictionary, more than one item
-
Oct 21st, 2021, 09:00 AM
#4
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.
-
Oct 21st, 2021, 09:12 AM
#5
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...
-
Oct 21st, 2021, 09:46 AM
#6
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
-
Forum Rules
|
Click Here to Expand Forum to Full Width
|