এটি গৃহীত উত্তর হিসাবে একই, তবে আমি Update
পাশাপাশি পদ্ধতিগুলি সরবরাহ করেছিলাম এবং আরও কিছুটা কমিয়ে ফেলেছি :
public class BiDictionary<TKey1, TKey2> : IEnumerable<Tuple<TKey1, TKey2>>
{
Dictionary<TKey1, TKey2> _forwards;
Dictionary<TKey2, TKey1> _reverses;
public int Count
{
get
{
if (_forwards.Count != _reverses.Count)
throw new Exception("somewhere logic went wrong and your data got corrupt");
return _forwards.Count;
}
}
public ICollection<TKey1> Key1s
{
get { return _forwards.Keys; }
}
public ICollection<TKey2> Key2s
{
get { return _reverses.Keys; }
}
public BiDictionary(IEqualityComparer<TKey1> comparer1 = null, IEqualityComparer<TKey2> comparer2 = null)
{
_forwards = new Dictionary<TKey1, TKey2>(comparer1);
_reverses = new Dictionary<TKey2, TKey1>(comparer2);
}
public bool ContainsKey1(TKey1 key)
{
return ContainsKey(key, _forwards);
}
private static bool ContainsKey<S, T>(S key, Dictionary<S, T> dict)
{
return dict.ContainsKey(key);
}
public bool ContainsKey2(TKey2 key)
{
return ContainsKey(key, _reverses);
}
public TKey2 GetValueByKey1(TKey1 key)
{
return GetValueByKey(key, _forwards);
}
private static T GetValueByKey<S, T>(S key, Dictionary<S, T> dict)
{
return dict[key];
}
public TKey1 GetValueByKey2(TKey2 key)
{
return GetValueByKey(key, _reverses);
}
public bool TryGetValueByKey1(TKey1 key, out TKey2 value)
{
return TryGetValue(key, _forwards, out value);
}
private static bool TryGetValue<S, T>(S key, Dictionary<S, T> dict, out T value)
{
return dict.TryGetValue(key, out value);
}
public bool TryGetValueByKey2(TKey2 key, out TKey1 value)
{
return TryGetValue(key, _reverses, out value);
}
public bool Add(TKey1 key1, TKey2 key2)
{
if (ContainsKey1(key1) || ContainsKey2(key2))
return false;
AddOrUpdate(key1, key2);
return true;
}
public void AddOrUpdateByKey1(TKey1 key1, TKey2 key2)
{
if (!UpdateByKey1(key1, key2))
AddOrUpdate(key1, key2);
}
private void AddOrUpdate(TKey1 key1, TKey2 key2)
{
_forwards[key1] = key2;
_reverses[key2] = key1;
}
public void AddOrUpdateKeyByKey2(TKey2 key2, TKey1 key1)
{
if (!UpdateByKey2(key2, key1))
AddOrUpdate(key1, key2);
}
public bool UpdateKey1(TKey1 oldKey, TKey1 newKey)
{
return UpdateKey(oldKey, _forwards, newKey, (key1, key2) => AddOrUpdate(key1, key2));
}
private static bool UpdateKey<S, T>(S oldKey, Dictionary<S, T> dict, S newKey, Action<S, T> updater)
{
T otherKey;
if (!TryGetValue(oldKey, dict, out otherKey) || ContainsKey(newKey, dict))
return false;
Remove(oldKey, dict);
updater(newKey, otherKey);
return true;
}
public bool UpdateKey2(TKey2 oldKey, TKey2 newKey)
{
return UpdateKey(oldKey, _reverses, newKey, (key1, key2) => AddOrUpdate(key2, key1));
}
public bool UpdateByKey1(TKey1 key1, TKey2 key2)
{
return UpdateByKey(key1, _forwards, _reverses, key2, (k1, k2) => AddOrUpdate(k1, k2));
}
private static bool UpdateByKey<S, T>(S key1, Dictionary<S, T> forwards, Dictionary<T, S> reverses, T key2,
Action<S, T> updater)
{
T otherKey;
if (!TryGetValue(key1, forwards, out otherKey) || ContainsKey(key2, reverses))
return false;
if (!Remove(otherKey, reverses))
throw new Exception("somewhere logic went wrong and your data got corrupt");
updater(key1, key2);
return true;
}
public bool UpdateByKey2(TKey2 key2, TKey1 key1)
{
return UpdateByKey(key2, _reverses, _forwards, key1, (k1, k2) => AddOrUpdate(k2, k1));
}
public bool RemoveByKey1(TKey1 key)
{
return RemoveByKey(key, _forwards, _reverses);
}
private static bool RemoveByKey<S, T>(S key, Dictionary<S, T> keyDict, Dictionary<T, S> valueDict)
{
T otherKey;
if (!TryGetValue(key, keyDict, out otherKey))
return false;
if (!Remove(key, keyDict) || !Remove(otherKey, valueDict))
throw new Exception("somewhere logic went wrong and your data got corrupt");
return true;
}
private static bool Remove<S, T>(S key, Dictionary<S, T> dict)
{
return dict.Remove(key);
}
public bool RemoveByKey2(TKey2 key)
{
return RemoveByKey(key, _reverses, _forwards);
}
public void Clear()
{
_forwards.Clear();
_reverses.Clear();
}
public IEnumerator<Tuple<TKey1, TKey2>> GetEnumerator()
{
if (_forwards.Count != _reverses.Count)
throw new Exception("somewhere logic went wrong and your data got corrupt");
foreach (var item in _forwards)
yield return Tuple.Create(item.Key, item.Value);
}
IEnumerator IEnumerable.GetEnumerator()
{
return GetEnumerator();
}
}
এখানে আমার উত্তর অনুরূপ
কয়েকটি বিষয় লক্ষণীয়:
আমি কেবল প্রয়োগ করেছি IEnumerable<>
। আমি মনে করি না ICollection<>
যেহেতু পদ্ধতির নামগুলি এই বিশেষ সংগ্রহ কাঠামোর জন্য সমস্ত পদ্ধতিই আলাদা হতে পারে। কী ভিতরে যেতে হবে তা সিদ্ধান্ত নিতে হবে IEnumerable<>
। সুতরাং এখন আপনার কাছে সংগ্রহ আরম্ভকারী সিনট্যাক্সও রয়েছে, পছন্দ করুন
var p = new BiDictionary<int, string> { 1, "a" }, { 2, "b" } };
আমি কিছু অদ্ভুত ব্যতিক্রম এখানে এবং সেখানে নিক্ষেপ করার চেষ্টা করেছি - কেবল ডেটা অখণ্ডতার জন্য। কেবল নিরাপদ দিকে থাকতে যাতে আপনি জানতে পারেন যে আমার কোডগুলিতে কি কোনও বাগ রয়েছে।
পারফরম্যান্স: আপনি যে Value
কোনও একটির সাথে অনুসন্ধান করতে পারেন Keys
যার অর্থ Get
এবং Contains
পদ্ধতির জন্য কেবলমাত্র 1 টি লুক (ও (1)) প্রয়োজন। Add
2 লুক এবং 2 টি অ্যাড দরকার। Update
1 লুক এবং 2 টি অ্যাড প্রয়োজন। Remove
3 টি লুকআপ লাগে। গৃহীত উত্তরের মতো সমস্ত।