9
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
2

6 Answers 6

7

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

Sign up to request clarification or add additional context in comments.

Comments

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.

7 Comments

You might want to try 'myDict.FirstOrDefault(pair => pair.Value == "what you want").Key;' instead.
@aloneguid you care to explain?
@Baboon your example will return results in O(n) instead of O(1). You can get O(1) by using the second dictionary.
@Clinton Building the second dictionary takes away the advantage you get by using it.
-1 this solution doesn't ensure a unique second key. Use two dictionaries.
|
5

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]);
        }
      }
    }    
  }
}

1 Comment

Very useful but when you call a data that no exists the function not works
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).

1 Comment

Consider a spanish/english dictionary. You can do lookups both ways. Although that's more like 2 dictionaries...
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.

Comments

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}");
        }

1 Comment

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.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.