1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160
| using System; using System.Collections; using System.Collections.Generic; using System.Linq; using UnityEngine;
public class SDictionary { }
[Serializable] public class SDictionary<TKey, TValue> : SDictionary, ISerializationCallbackReceiver, IDictionary<TKey, TValue> { [SerializeField] private List<SKeyValue<TKey,TValue>> list = new List<SKeyValue<TKey, TValue>>();
private Dictionary<TKey, int> KeyPositions => _keyPositions.Value; private Lazy<Dictionary<TKey, int>> _keyPositions;
public SDictionary() { _keyPositions = new Lazy<Dictionary<TKey, int>>(MakeKeyPositions); }
private Dictionary<TKey, int> MakeKeyPositions() { var dictionary = new Dictionary<TKey, int>(list.Count); for (var i = 0; i < list.Count; i++) { dictionary[list[i].Key] = i; } return dictionary; }
public void OnBeforeSerialize() { }
public void OnAfterDeserialize() { _keyPositions = new Lazy<Dictionary<TKey, int>>(MakeKeyPositions); }
#region IDictionary<TKey, TValue>
public TValue this[TKey key] { get => list[KeyPositions[key]].Value; set { var pair = new SKeyValue<TKey,TValue>(key, value); if (KeyPositions.ContainsKey(key)) { list[KeyPositions[key]] = pair; } else { KeyPositions[key] = list.Count; list.Add(pair); } } }
public ICollection<TKey> Keys => list.Select(tuple => tuple.Key).ToArray(); public ICollection<TValue> Values => list.Select(tuple => tuple.Value).ToArray();
public void Add(TKey key, TValue value) { if (KeyPositions.ContainsKey(key)) throw new ArgumentException("An element with the same key already exists in the dictionary."); else { KeyPositions[key] = list.Count; list.Add(new SKeyValue<TKey, TValue>(key, value)); } }
public bool ContainsKey(TKey key) => KeyPositions.ContainsKey(key);
public bool Remove(TKey key) { if (KeyPositions.TryGetValue(key, out var index)) { KeyPositions.Remove(key);
list.RemoveAt(index); for (var i = index; i < list.Count; i++) KeyPositions[list[i].Key] = i;
return true; } else return false; }
public bool TryGetValue(TKey key, out TValue value) { if (KeyPositions.TryGetValue(key, out var index)) { value = list[index].Value; return true; } else { value = default; return false; } }
#endregion
#region ICollection <KeyValuePair<TKey, TValue>>
public int Count => list.Count; public bool IsReadOnly => false;
public void Add(KeyValuePair<TKey, TValue> kvp) => Add(kvp.Key, kvp.Value);
public void Clear() => list.Clear(); public bool Contains(KeyValuePair<TKey, TValue> kvp) => KeyPositions.ContainsKey(kvp.Key);
public void CopyTo(KeyValuePair<TKey, TValue>[] array, int arrayIndex) { var numKeys = list.Count; if (array.Length - arrayIndex < numKeys) throw new ArgumentException("arrayIndex"); for (var i = 0; i < numKeys; i++, arrayIndex++) { var entry = list[i]; array[arrayIndex] = new KeyValuePair<TKey, TValue>(entry.Key, entry.Value); } }
public bool Remove(KeyValuePair<TKey, TValue> kvp) => Remove(kvp.Key);
public Dictionary<TKey, TValue> ToDictionary() { Dictionary<TKey, TValue> dic = new Dictionary<TKey, TValue>(); foreach(var kvp in list) { dic.Add(kvp.Key, kvp.Value); } return dic; }
#endregion
#region IEnumerable <KeyValuePair<TKey, TValue>>
public IEnumerator<KeyValuePair<TKey, TValue>> GetEnumerator() { return list.Select(ToKeyValuePair).GetEnumerator();
static KeyValuePair<TKey, TValue> ToKeyValuePair(SKeyValue<TKey, TValue> skvp) { return new KeyValuePair<TKey, TValue>(skvp.Key, skvp.Value); } }
IEnumerator IEnumerable.GetEnumerator() => GetEnumerator();
#endregion }
|