2.0 - is there a generic for this?

LookitsPuck

Active member
Joined
Jan 23, 2007
Messages
37
Programming Experience
3-5
Alright, I have a queue of objects that I'd like to implement with an ID as the key.

Right now I'm using a Dictionary object, but it's not giving me the functionality I want (FIFO). I can't use a list, because there's no key that I can use there to access the object.

Basically, I have a list of people waiting in line with certain IDs. I have processes that remove them from line based on their ID rather than iterating through, getting a reference to that object, then removing it via that (I could use a Generic list to do that).

Right now, I'm using a Dictionary object (Generic Dictionary) which allows me to use the key to access/add/remove the object, but the objects are not added or listed the way I plan them to be.

Is there an object that I'm overlooking? Something custom I need to create? Or something someone already created?

Basically I'm looking for the FIFO power of a List, with the immediate lookup of a Dictionary which has a key to access the object and the object stored at that key location.

Thanks
-Steve
 
I'm confused.... why would you need to access them by key if you are using FIFO? Seems to me you should only be concerned with the object at the head of the line.... removing from there..

-tg
 
If a person decides to leave the line and they're in the middle of it. I'd like to nix them by key instead of iterating through, finding the position/item, and removing that.
 
The person can call to the lsit and request a removal - but you have implied you want to find them by their key and remove them - ergo they are not removing themselves, you are removing them.

Can you better explain what it is youre actually trying to achieve? FIFO implies a svery specificorder, indexing by key requires disorder (order according to the hashing of the key, which is rarely FIFO)

It sounds like you need a custom implementation of both a dictionary and a list. In removing itself from the list, the entity must join its next and previous together:

realNext = .Next
realPrevious = .Previous
.Previous.Next = realNext
.Next.Previous = realPrevious

then remove itself from the dictionary
 
Sure, I can explain.

It's actually a game. In the game, you're in a room. In that room, you can pick which user you want to race, what type of race, and what car of theirs you want to race against. If they accept, it adds you to a list. Should be ordered by FIFO.

However, if users disconnect or one of the racers decides that he/she doesn't want to race, they leave/disconnect, and it removes them from that list.

So, I join a room, and there are 3 rivals in line:
A vs. B
C vs. D
E vs. F

I (G) want to challenge (H). So I get appended to the end of the line. It is now:

A vs. B
C vs. D
E vs. F
G vs. H

E decides he doesn't want to race, so he gets bumped, it's now:
A vs. B
C vs. D
G vs. H

I'd like to remove them by key, which is their accountID, and such is unique. That's how they're stored currently by dictionary:

Dictionary(Of Int32, RivalsInfo)

Int32 is of course the accountID of the challenger.

So I definitely need a custom implementation of a dictionary/list. Not sure how to go about it or if there's something out there that can achieve those goals.
 
Just an idea, here is an inherited LinkedList that includes the common Queue class methods Enqueue and Dequeue and also allows to remove an item from the queue by key (id).

First quickly defined some item class:
VB.NET:
Class qItem
    Public ID As Integer, Name As String
    Public Sub New(ByVal id As Integer, ByVal name As String)
        Me.ID = id
        Me.Name = name
    End Sub
End Class
Here is the special 'linked queue' class:
VB.NET:
Class llQueue
    Inherits LinkedList(Of qItem)
 
    Public Sub Enqueue(ByVal q As qItem)
        Me.AddLast(q)
    End Sub
 
    Public Function Dequeue() As qItem
        If Me.Count = 0 Then Return Nothing
        Dim q As qItem = Me.First.Value
        Me.RemoveFirst()
        Return q
    End Function
 
    Public Overloads Sub Remove(ByVal key As Integer)
        Dim q As qItem = Me.Find(key)
        If Not q Is Nothing Then Me.Remove(q)
    End Sub
 
    Private Overloads Function Find(ByVal key As Integer) As qItem
        For Each q As qItem In Me
            If q.ID = key Then Return q
        Next
        Return Nothing
    End Function
End Class
Here example using it:
VB.NET:
[COLOR=darkgreen]'enqueue some items[/COLOR]
Dim ll As New llQueue
ll.Enqueue(New qItem(11, "item11"))
ll.Enqueue(New qItem(22, "item22"))
ll.Enqueue(New qItem(33, "item33"))
[COLOR=darkgreen]'remove an item by key[/COLOR]
ll.Remove(22)
[COLOR=darkgreen]'dequeue and see rest of queue[/COLOR]
Dim q As qItem
q = ll.Dequeue
MsgBox(q.Name)
q = ll.Dequeue
MsgBox(q.Name)
 
Very nice, John. I dig!

I went somewhere along these lines:

VB.NET:
Namespace Collections
    Public Class LinkedQueueItem
        Private _ID As Int32
        Private _value As Object

        Public Property ID() As Int32
            Get
                Return _ID
            End Get
            Set(ByVal value As Int32)
                _ID = value
            End Set
        End Property

        Public Property Value() As Object
            Get
                Return _value
            End Get
            Set(ByVal value As Object)
                _value = value
            End Set
        End Property

        Public Sub New(ByVal id As Int32, ByVal value As Object)
            Me.ID = id
            Me.Value = value
        End Sub
    End Class

    Public Class LinkedQueue
        Inherits LinkedList(Of LinkedQueueItem)

        Public Sub Enqueue(ByVal q As LinkedQueueItem)
            Me.AddLast(q)
        End Sub

        Public Function Dequeue() As LinkedQueueItem
            If Me.Count = 0 Then Return Nothing
            Dim q As LinkedQueueItem = Me.First.Value
            Me.RemoveFirst()
            Return q
        End Function

        Public Overloads Sub Remove(ByVal key As Int32)
            Dim q As LinkedQueueItem = Me.Find(key)
            If q IsNot Nothing Then Me.Remove(q)
        End Sub

        Public Overloads Function Find(ByVal key As Int32) As LinkedQueueItem
            For Each q As LinkedQueueItem In Me
                If (q.ID = key) Then Return q
            Next
            Return Nothing
        End Function
    End Class
End Namespace

My only problem is having an object of type Object in the collection rather than a heavily casted object using templates or something along the same line that generics use (Of T). Is there a way to make this a bit more type safe?
 
Last edited:
The Idea was that the 'qItem' should be your item class, which of the llQueue was a typesafe collection for.
As it looks you are creating yet another wrapper class?
 
When you post code.. please put the editor in simple mode (bright white background) by clicking this button in the TOP RIGHT:



switchmode.gif



This will stop it becoming an unindented dogs dinner!
 
The Idea was that the 'qItem' should be your item class, which of the llQueue was a typesafe collection for.
As it looks you are creating yet another wrapper class?

Well, this is a type of class that I might reuse later down the line, so I'd like to put it into my class library that I have for the company I work. So I wouldn't want to just have it chained down to one type of object, whether it be a string, integer, or an actual class, etc.
 
Any idea?

Just trying to find a way where I could do this:

VB.NET:
    Public Class LinkedQueue
        Inherits LinkedList(Of GenericType)

Where GenericType is however the framework defines a variable type. This way I don't have to use a predefined object for it. Any idea how this happens in the background?
 
Asking how .NET 2,0 implements generics is perhaps beyond the scope of the thread,, have you tried a google search?
Read the article in my previous post. That's how they wrote the generics classes.
 
Back
Top