How to do reverse dictionary lookups

I have a type dictionary <string, string>, and for a specific case I need to do a reverse lookup. So, for example, suppose I have this entry <"SomeString", "ab">, and that I pass in "ab", then I would like to return "SomeString". Before I start the loop foreachfor each entry in the dictionary, I was wondering what would be the most efficient way to do this reverse lookup?

+18
source share
5 answers

Basically, you can use LINQand get Key, like this, without changing anything:

var key = dictionary.FirstOrDefault(x => x.Value == "ab").Key;

If you really want to cancel your dictionary, you can use the extension method as follows:

public static Dictionary<TValue, TKey> Reverse<TKey, TValue>(this IDictionary<TKey, TValue> source)
{
     var dictionary = new Dictionary<TValue, TKey>();
     foreach (var entry in source)
     {
         if(!dictionary.ContainsKey(entry.Value))
             dictionary.Add(entry.Value, entry.Key);
     }
     return dictionary;
} 

Then you can use it as follows:

var reversedDictionary = dictionary.Reverse();
var key = reversedDictionary["ab"];

: , Value .

+32

Linq ToDictionary:

var reversed = d.ToDictionary(x => x.Value, x => x.Key);

, , Linqpad:

var d = new Dictionary<int, string>();
d.Add(1,"one");
d.Add(2,"two");
d.Dump(); //prints it out in linq-pad
var reversed = d.ToDictionary(x => x.Value, x => x.Key);
reversed.Dump(); //prints it out in linq-pad

Prints

+24

linq ToDictionary:

var reversedDictionary = dictionary.ToDictionary(x => x.Value, x => x.Key);
+4

1) , . .

2) - O(log n). foreach LINQ O(n).

,
A: LINQ, O(n) , .
B: Dictionary<ValueType, HashSet<KeyType>>, O(log n) , O(n) . ( : , )

+2

(> ) , . , IDictionary (Of TKey, TValue), .

: , , "s", "sec", "second" "seconds" "second", .

: ( VB.net, )

Imports System
Imports System.Collections.Generic
Imports System.Runtime.CompilerServices

Public Class TimeUnit

    Private ReadOnly _name As String

    Public Sub New(ByVal name As String, ByVal avgSpan As TimeSpan)
        _name = name
        _AvgSpan = avgSpan
    End Sub

    Public ReadOnly Property AvgSpan() As TimeSpan

    Public Overrides Function ToString() As String
        Return _name
    End Function

End Class

Public Class TimeUnits

    Private ReadOnly _items As New Dictionary(Of String, TimeUnit)(37, StringComparer.OrdinalIgnoreCase) _
        From {{{"n", "min", "minute", "minutes", "minuten"},
               New TimeUnit("Minute", TimeSpan.FromMinutes(1))},
              {{"h", "std", "stunde", "hour", "stunden", "hours"},
               New TimeUnit("Hour", TimeSpan.FromHours(1))},
              {{"d", "t", "day", "tag", "days", "tage"},
               New TimeUnit("Day", TimeSpan.FromDays(1))},
              {{"m", "mo", "month", "monat", "months", "monate"},
               New TimeUnit("Month", TimeSpan.FromDays(30.4375))},
              {{"q", "quarter", "quartal", "quarters", "quartale"},
               New TimeUnit("Quarter", TimeSpan.FromDays(91.3125))},
              {{"y", "yy", "yyy", "yyyy", "j", "year", "jahr", "years", "jahre"},
               New TimeUnit("Year", TimeSpan.FromDays(365.25))}}

    Public Function GetByAbbreviation(ByVal abbreviation As String) As TimeUnit
        Return _items(abbreviation)
    End Function

End Class

Public Module ExtensionMethods
    <Extension>
    Public Sub Add(Of TKey, TValue)(ByVal valItems As IDictionary(Of TKey, TValue), ByVal valKeys As IEnumerable(Of TKey), ByVal valValue As TValue)
        For Each tempKey As TKey In valKeys
            valItems.Add(tempKey, valValue)
        Next
    End Sub
End Module

Public Module Main
    Public Sub Main()
        Dim name As String = "Jahr"
        Console.WriteLine(String.Format("The time unit for '{0}' is {1}.", name, (New TimeUnits).GetByAbbreviation(name)))
    End Sub
End Module

: "" - .

0

Source: https://habr.com/ru/post/1694385/


All Articles