8
public static Dictionary<int, string> dic = new Dictionary<int, string>() { 
            {1,"anystring1"},
            {2,"anystring2"}};

I need to use this

string str= dic[1]; // it is possible

int a=dic["anystring1"]; // My dream is it
ebattulga
  • 10,774
  • 20
  • 78
  • 116

6 Answers6

7

Use another Dictionary<> and use it in reverse order of key/value.

Daniel Mošmondor
  • 19,718
  • 12
  • 58
  • 99
6

I'm a bit late on this one, but LINQ is your friend here:

MyDict.FirstOrDefault(pair => pair.Value == "the value you want").Key;

Allows you to do what you want.

Bob
  • 217
  • 1
  • 4
  • 11
Louis Kottmann
  • 16,268
  • 4
  • 64
  • 88
  • 2
    You might want to try 'myDict.FirstOrDefault(pair => pair.Value == "what you want").Key;' instead. – Nobody Feb 06 '12 at 01:03
  • @aloneguid you care to explain? – Louis Kottmann Mar 23 '12 at 18:27
  • @Baboon your example will return results in O(n) instead of O(1). You can get O(1) by using the second dictionary. – Clinton Mar 19 '13 at 02:40
  • @Clinton Building the second dictionary takes away the advantage you get by using it. – Louis Kottmann Mar 19 '13 at 13:38
  • -1 this solution doesn't ensure a unique second key. Use two dictionaries. – Alex Mar 28 '13 at 16:13
  • @AlexG The OP did not put such constraint. This is the quick version, for a unique second key you need to define a BiLookup class. – Louis Kottmann Mar 28 '13 at 17:56
  • It's implicit in the dictionary contract and it's also slower as Clinton mentioned. Perhaps a downvote was too harsh - I now can't retract it, sorry - but this 'quick version' is not an appropriate solution for the majority of the problem space. – Alex Mar 29 '13 at 18:03
4

I wish this was in the System library, but it's pretty easy to roll your own.

Below, I'll provide the skeleton of writing such a class, whose usage looks like:

var twoWayDict = new TwoWayDict<string, int>();

twoWayDict["zero"] = 0;
// twoWayDict["zero"] == 0
// twoWayDict.Reverse[0] == "zero"

twoWayDict.Reverse[1] = "one";
// twoWayDict["one"] == 1
// twoWayDict.Reverse[1] == "one"

Keep in mind, one gotcha for a two way dictionary is that you should expect all input to be tightly coupled. In other words, if you re-use a key OR a value, you will erase the data previous linked with either:

twoWayDict["zero"] = 0;

// Then later...
twoWayDict.Reverse[0] = "ZERO";
// Now twoWayDict["ZERO"] == 0

// Later still...
// Exception: Key not found! "zero" was dropped when you re-used value 0
Console.WriteLine(twoWayDict["zero"]); 

Finally, here's some sample code. It's minimal - it should act as a foundation for anyone who wants to flesh out their own version. Note that I implement a wrapper class so I can provide a "Reverse" property without directly exposing the internal dictionary.

// Generics note: K indicates "key" type and V indicates "value" type
using System.Collections.Generic;

namespace YourNamespaceHere.Collections
{
  public class TwoWayDict<K, V>
  {
    private Dictionary<K, V> _dictKV;
    private Dictionary<V, K> _dictVK;
    private ReverseDict _reverseDict;

    public TwoWayDict()
    {
      _dictKV = new Dictionary<K, V>();
      _dictVK = new Dictionary<V, K>();
      _reverseDict = new ReverseDict(this);
    }

    public ReverseDict Reverse
    {
      get { return _reverseDict; }
    }

    // TwoWayDict[key] -> value
    public V this[K key]
    {
      get { return _dictKV[key]; }
      set
      {
        // Remove any existing key/value pair
        Remove(key);

        _dictKV[key] = value;
        _dictVK[value] = key;
      }
    }

    public void Remove(K key)
    {
      if (_dictKV.ContainsKey(key))
      {
         _dictVK.Remove(_dictKV[key]);
         _dictKV.Remove(key);
      }
    }

    // Wrapper that allows TwoWayDict to expose a convenient
    // 'Reverse' property.
    public class ReverseDict
    {
      private TwoWayDict<K, V> _parent;
      public ReverseDict(TwoWayDict<K, V> parent)
      {
         _parent = parent;
      }

      public K this[V reverseKey]
      {
        get { return _parent._dictVK[reverseKey]; }
        set { _parent[value] = reverseKey; }
      }

      public void Remove(V value)
      {
        if (_parent._dictVK.ContainsKey(value))
        {
          _parent.Remove(_parent._dictVK[value]);
        }
      }
    }    
  }
}
dherman
  • 495
  • 6
  • 7
3

That is not what a dictionary is meant to do. Can you think of a definition and instantly find the matching word in your favorite dictionary in O(1) time? If you want a class with that type of functionality (a bidirectional dictionary) you will have to build it yourself (or Google for one of many implementations on the Internet).

jason
  • 236,483
  • 35
  • 423
  • 525
0

I actually use a class that combines an ArrayList with a Dictionary so that I can look up child nodes based on name or order added, and maintain the original order of the objects as they were added.

Objects are added to the ArrayList first, then the index of that object in the ArrayList is added to the dictionary using the desired key.

This allows me to access either by key or position, in a very optimal way, while maintaining the order of the objects as they were added.

Gotcha areas to watch for are adding another object using an existing key, which will orphan the original object and removing any element from the vector which will cause the indices in the Dictionary to become corrupted, pointing to the wrong values.

Just thought I would share my two cents worth - hope it helps someone.

Rodney P. Barbati
  • 1,883
  • 24
  • 18
0
        Dictionary<string, int> d = new Dictionary<string, int>();

        foreach (var item in ads)
        {


            if (d.ContainsKey(item.categoryName))
            {
                d[item.categoryName]++;
            }
            else
            {
                d.Add(item.categoryName, 1);
            }
        }

        foreach (var item in d)
        {
            Console.WriteLine($"\t{item.Key}: {item.Value}");
        }
KennetsuR
  • 704
  • 8
  • 17
VSC
  • 1
  • 1
    Your answer could be improved with additional supporting information. Please [edit] to add further details, such as citations or documentation, so that others can confirm that your answer is correct. You can find more information on how to write good answers [in the help center](/help/how-to-answer). – Community May 31 '23 at 13:59