Can I make sure that in dictionary in C# there will be only a single of a specific value in it?

For example, if I define a Dictionary which key is char and value is char, can I make sure that if the character 'a' is already an existing value, there won't be another value 'a' in the dictionary?

I have a solution, but I'd like to know if there's a better one:

static void Main()
{
    Dictionary<int, int> dic = new Dictionary<int, int>();
    bool valExists = false;
    Console.WriteLine("please enter key and value");
    int key = int.Parse(Console.ReadLine());
    int val = int.Parse(Console.ReadLine());
    foreach (KeyValuePair<int,int> keyval in dic)
    {
        if (keyval.Value == val)
        {
            valExists = true;
            break;
        }
    }
    if (!valExists)
        dic.Add(key, val);
}
有帮助吗?

解决方案

Can I make sure that in dictionary in C# there will be only a single of a specific value in it?

Not as such (it wouldn't follow the the normal dictionary contract at that point), but it sounds like you effectively want a bi-directional dictionary. You can do that by composing two dictionaries, one going in each direction. I have an answer on another question with sample code for that.

That will allow you to go directly from "value" to "key" - if you have no need for that, you could always just keep a HashSet<TValue> as well as the normal TDictionary<TKey, TValue> and throw an exception if the caller tries to add a value which already exists.

Again, I would urge you not to do this by deriving from Dictionary<,> - instead just compose a Dictionary<,> and a HashSet<>. (I wouldn't even implement IDictionary<,>, as you have additional constraints which normal dictionaries don't include.)

其他提示

There's a built in method on the dictionary class to check if values exist. Note that this is a linear search, so it's not the most efficient way, but it does exist...

static void Main()
{
    Dictionary<int, int> dic = new Dictionary<int, int>();

    Console.WriteLine("please enter key and value");
    int key = int.Parse(Console.ReadLine());
    int val = int.Parse(Console.ReadLine());

    if (!dic.ContainsValue(val))
        dic.Add(key, val);
}

To avoid needing to do a linear search through the entire dictionary for each Add you can keep a HashSet<TValue> as well as the dictionary. When you add a new value, you can first check the set. If it's there, it's in the dictionary. If you end up adding the item, add it to the set. When removing items from the dictionary you also need to remove them from the set.

This tells you if you have duplicate values or not:

dic.Values.Distinct().Count() == dic.Values.Count() // true if no duplicates found

To prevent duplicates:

if (!dic.ContainsValue(val)) {    
  dic[key] = val;
}

For better performance, use a seaparate HashSet.

var values = new HashSet<int>();

if (!values.Contains(val)) {
  values.Add(val);
  dic[key] = val;
}
许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top