Last active
June 18, 2020 08:01
-
-
Save SolidAlloy/9d77972f0bb1f0be91f63af66417c815 to your computer and use it in GitHub Desktop.
A dictionary implementation that generates keys automatically and returns them in the Add() method.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// A dictionary implementation that generates keys automatically and returns them in the Add() method. | |
// This is basically a nicely presented copy of the code snippet from this post | |
// https://stackoverflow.com/a/39104018/9833103 | |
namespace CustomDataStructures | |
{ | |
using System; | |
using System.Collections; | |
using System.Collections.Generic; | |
internal class AutoKeyDictionary<TKey, TValue> : IEnumerable<KeyValuePair<TKey, TValue>> | |
{ | |
private readonly Dictionary<TKey, TValue> _inner; | |
private readonly Func<TKey, TKey> _incrementor; | |
private readonly Stack<TKey> _freeKeys; | |
private readonly TKey _keySeed; | |
private TKey _currentKey; | |
public AutoKeyDictionary(TKey keySeed, Func<TKey, TKey> incrementor) | |
{ | |
if (keySeed == null) | |
throw new ArgumentNullException(nameof(keySeed)); | |
if (incrementor == null) | |
throw new ArgumentNullException(nameof(incrementor)); | |
_inner = new Dictionary<TKey, TValue>(); | |
_freeKeys = new Stack<TKey>(); | |
_currentKey = keySeed; | |
} | |
public int Count => _inner.Count; | |
public Dictionary<TKey, TValue>.KeyCollection Keys => _inner.Keys; | |
public Dictionary<TKey, TValue>.ValueCollection Values => _inner.Values; | |
public TValue this[TKey key] { get => _inner[key]; set => _inner[key] = value; } | |
public TKey Add(TValue value) // returns the used key | |
{ | |
TKey usedKey; | |
if (_freeKeys.Count > 0) | |
{ | |
usedKey = _freeKeys.Pop(); | |
_inner.Add(usedKey, value); | |
} | |
else | |
{ | |
usedKey = _currentKey; | |
_inner.Add(usedKey, value); | |
_currentKey = _incrementor(_currentKey); | |
} | |
return usedKey; | |
} | |
public void Clear() | |
{ | |
_inner.Clear(); | |
_freeKeys.Clear(); | |
_currentKey = _keySeed; | |
} | |
public bool Remove(TKey key) | |
{ | |
if (!_inner.Remove(key)) | |
return false; | |
if (_inner.Count > 0) | |
{ | |
_freeKeys.Push(key); | |
} | |
else | |
{ | |
_freeKeys.Clear(); | |
_currentKey = _keySeed; | |
} | |
return true; | |
} | |
public bool TryGetValue(TKey key, out TValue value) | |
{ | |
return _inner.TryGetValue(key, out value); | |
} | |
public bool ContainsKey(TKey key) | |
{ | |
return _inner.ContainsKey(key); | |
} | |
public bool ContainsValue(TValue value) | |
{ | |
return _inner.ContainsValue(value); | |
} | |
public IEnumerator<KeyValuePair<TKey, TValue>> GetEnumerator() | |
{ | |
return _inner.GetEnumerator(); | |
} | |
IEnumerator IEnumerable.GetEnumerator() | |
{ | |
return ((IEnumerable)_inner).GetEnumerator(); | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment