GARbro-mirror/GameRes/MultiDict.cs

165 lines
6.0 KiB
C#
Raw Normal View History

2014-07-22 03:26:28 +08:00
//! \file GameRes.cs
//! \date Mon Jun 30 20:12:13 2014
//! \brief game resources browser.
//
// copy-pasted from some post on the stackoverflow.
//
2014-07-22 03:26:28 +08:00
using System;
using System.Collections.Generic;
namespace GameRes.Collections
{
/// <summary>
/// Extension to the normal Dictionary. This class can store more than one value for every key.
/// It keeps a HashSet for every Key value. Calling Add with the same Key and multiple values
/// will store each value under the same Key in the Dictionary. Obtaining the values for a Key
/// will return the HashSet with the Values of the Key.
/// </summary>
/// <typeparam name="TKey">The type of the key.</typeparam>
/// <typeparam name="TValue">The type of the value.</typeparam>
public class MultiValueDictionary<TKey, TValue> : Dictionary<TKey, HashSet<TValue>> //, IEnumerable<KeyValuePair<TKey, TValue>>, System.Collections.IEnumerable
{
/// <summary>
/// Initializes a new instance of the <see cref="MultiValueDictionary&lt;TKey, TValue&gt;"/> class.
/// </summary>
public MultiValueDictionary() : base()
{
}
/// <summary>
/// Adds the specified value under the specified key
/// </summary>
/// <param name="key">The key.</param>
/// <param name="value">The value.</param>
public void Add(TKey key, TValue value)
{
HashSet<TValue> container = null;
if(!this.TryGetValue(key, out container))
{
container = new HashSet<TValue>();
base.Add(key, container);
}
container.Add(value);
}
/// <summary>
/// Removes the specified value for the specified key. It will leave the key in the dictionary.
/// </summary>
/// <param name="key">The key.</param>
/// <param name="value">The value.</param>
public void Remove(TKey key, TValue value)
{
HashSet<TValue> container = null;
if(this.TryGetValue(key, out container))
{
container.Remove(value);
if(container.Count <= 0)
{
this.Remove(key);
}
}
}
/// <summary>
/// Gets the values for the key specified. This method is useful if you want to avoid an
/// exception for key value retrieval and you can't use TryGetValue (e.g. in lambdas)
/// </summary>
/// <param name="key">The key.</param>
/// <param name="returnEmptySet">if set to true and the key isn't found, an empty hashset is
/// returned, otherwise, if the key isn't found, null is returned</param>
/// <returns>
/// This method will return null (or an empty set if returnEmptySet is true) if the key
/// wasn't found, or the values if key was found.
/// </returns>
public HashSet<TValue> GetValues(TKey key, bool returnEmptySet)
{
HashSet<TValue> toReturn = null;
if (!base.TryGetValue(key, out toReturn) && returnEmptySet)
{
toReturn = new HashSet<TValue>();
}
return toReturn;
}
/*
// hides Dictionary.GetEnumerator()
new public IEnumerator<KeyValuePair<TKey, TValue>> GetEnumerator()
{
Enumerator e = new Enumerator();
e.key_enumerator = base.GetEnumerator();
e.current_pair = new KeyValuePair<TKey, TValue>();
if (e.key_enumerator.MoveNext())
e.value_enumerator = e.key_enumerator.Current.Value.GetEnumerator();
else
e.value_enumerator = null;
return e;
}
System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator()
{
return (System.Collections.IEnumerator)GetEnumerator();
}
[SerializableAttribute]
new public struct Enumerator : IEnumerator<KeyValuePair<TKey, TValue>>, IDisposable, System.Collections.IEnumerator
{
public Dictionary<TKey, HashSet<TValue>>.Enumerator key_enumerator;
public HashSet<TValue>.Enumerator? value_enumerator;
public KeyValuePair<TKey, TValue> current_pair;
public KeyValuePair<TKey, TValue> Current { get { return current_pair; } }
object System.Collections.IEnumerator.Current { get { return Current; } }
void IDisposable.Dispose() { }
void System.Collections.IEnumerator.Reset()
{
}
private void SetCurrent ()
{
current_pair = new KeyValuePair<TKey, TValue>(key_enumerator.Current.Key, value_enumerator.Value.Current);
Console.WriteLine("Enumerator.SetCurrent ({0} => {1})", current_pair.Key, current_pair.Value);
}
private void ResetCurrent ()
{
current_pair = new KeyValuePair<TKey, TValue>(default(TKey), default(TValue));
}
public bool MoveNext ()
{
if (null == value_enumerator)
{
ResetCurrent();
return false;
}
if (value_enumerator.Value.MoveNext())
{
SetCurrent();
return true;
}
if (!key_enumerator.MoveNext())
{
value_enumerator = null;
ResetCurrent();
return false;
}
value_enumerator = key_enumerator.Current.Value.GetEnumerator();
if (value_enumerator.Value.MoveNext())
{
SetCurrent();
return true;
}
else
{
current_pair = new KeyValuePair<TKey, TValue>(key_enumerator.Current.Key, default(TValue));
return false;
}
}
}
*/
}
}