Marcello
Marcello

Reputation: 448

create a dictionary with key as list(of string)

need to create a dictionary where keys are list(Of String) or array of string

i found this link C# List as Dictionary key

but i need an help to understand how to do it with list(of String)

Class test
    Sub TryTest()
        myDict.Add(New List(Of String) From {"Huey", "Dewey"}, actions.Sleeping)
        myDict.Add(New List(Of String) From {"Dewey", "Louie"}, actions.Playing)

        Dim newList As New List(Of String) From {"Dewey", "Louie"}
        If myDict.ContainsKey(newList) Then
            MsgBox("myDict contains the list of String, as Key Value")
        Else
            MsgBox("myDict don't contains the list of String, as Key Value")
        End If
    End Sub

    Dim myDict As New Dictionary(Of List(Of String), actions)

End Class

Enum actions
    Sleeping
    Eating
    Studying
    Playing
End Enum

I expected that the dictionary output that contains the key.

P.S. Since c# it's close to vb.net, and on the net there are lot's of c#/vb.net translators that translate easily, please, also c# help are appreciated.


UPDATE (after Jeppe Stig Nielsen helps, i tried to implement a class that inherits EqualityComparer, but it doesn't work... maybe i mistake something in syntax... do someone know what's wrong in my approach?


Class test
    Sub TryTest()
        myDict.Add(New List(Of String) From {"Huey", "Dewey"}, actions.Sleeping)
        myDict.Add(New List(Of String) From {"Dewey", "Louie"}, actions.Playing)

        Dim newList As New List(Of String) From {"Dewey", "Louie"}
        If myDict.ContainsKey(newList) Then
            MsgBox("myDict contains the list of String, as Key Value")
        Else
            MsgBox("myDict don't contains the list of String, as Key Value")
        End If

        Try
            myDict.Add(newList, actions.Eating)
        Catch ex As Exception
            MsgBox("myDict don't allow me to add an already present List (Of String), as Key Value")
        End Try

    End Sub

    Dim myDict As New Dictionary(Of List(Of String), actions)(New ListComparer)

End Class

Enum actions
    Sleeping
    Eating
    Studying
    Playing
End Enum

NotInheritable Class ListComparer
    Inherits EqualityComparer(Of List(Of String))

    Public Overrides Function Equals(ByVal x As List(Of String), ByVal y As List(Of String)) As Boolean
        Return StructuralComparisons.StructuralEqualityComparer.Equals(x, y)
    End Function

    Public Overrides Function GetHashCode(ByVal x As List(Of String)) As Integer
        Return StructuralComparisons.StructuralEqualityComparer.GetHashCode(x)
    End Function
End Class

Upvotes: 2

Views: 2839

Answers (2)

Jeppe Stig Nielsen
Jeppe Stig Nielsen

Reputation: 61952

With

using System.Collections;
using System.Collections.Generic;

you can create a class like

sealed class ListComparer : EqualityComparer<List<string>>
{
  public override bool Equals(List<string> x, List<string> y)
    => StructuralComparisons.StructuralEqualityComparer.Equals(x, y);

  public override int GetHashCode(List<string> x)
    => StructuralComparisons.StructuralEqualityComparer.GetHashCode(x);
}

and then use it as comparer for the Dictionary<,>

myDict = new Dictionary<List<string>, Actions>(new ListComparer());

The ListComparer class could also be generic, sealed class ListComparer<T> : EqualityComparer<List<T>>.


EDIT:

After comments, I realize that StructuralEqualityComparer does not work for List<string> (which I had thought)! It works for string[] and for stuff like Tuple<string, string, ...>. So the above class needs to be changed into:

sealed class ListComparer : EqualityComparer<List<string>>
{
  public override bool Equals(List<string> x, List<string> y)
    => StructuralComparisons.StructuralEqualityComparer.Equals(x?.ToArray(), y?.ToArray());

  public override int GetHashCode(List<string> x)
    => StructuralComparisons.StructuralEqualityComparer.GetHashCode(x?.ToArray());
}

My original attempt was wrong!

Upvotes: 3

DemiDev
DemiDev

Reputation: 31

problem is you comparing 2 object. you need to compare values in it. i dont know vb.net my code is c# (LINQ). do it like this.

var myDic = new Dictionary<List<string>, Actions>();
myDic.Add(new List<string>() { "Huey", "Dewey" }, Actions.Sleeping);
myDic.Add(new List<string>() { "Dewey", "Louie" }, Actions.Playing);
var newList = new List<string>() { "Dewey", "Louie" };
if (myDic.Keys.Any(key =>
{
    if (key.Count != newList.Count) return false;

    var same = true;
    for (int i = 0; i < newList.Count; i++)
    {
        if (key[i] != newList[i]) same = false;
    }
    return same;
}))
    MsgBox("myDict contains the list of String, as Key Value");
else
    MsgBox("myDict don't contains the list of String, as Key Value")

Upvotes: 0

Related Questions