Mega Code Archive

 
Categories / C# / Collections Data Structure
 

Dictionary List

#region License // Copyright Â© 2011 ?ukasz ?wi?tkowski // http://www.lukesw.net/ // // This library is free software: you can redistribute it and/or modify // it under the terms of the GNU Lesser General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // // This library is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the // GNU Lesser General Public License for more details. // // You should have received a copy of the GNU Lesser General Public License // along with this library.  If not, see <http://www.gnu.org/licenses/>. #endregion namespace Luminous.Collections {     using System;     using System.Collections.Generic;     using System.Diagnostics.Contracts;     using System.Linq;     using System.Text;     public class DictionaryList<T> : System.Collections.Generic.IList<T>     {         private Dictionary<int, T> _keyIsIndex;         private Dictionary<T, int> _keyIsObject;         private int _firstIndex;         private int _lastIndex;         private int _count;         public DictionaryList()         {             _keyIsIndex = new Dictionary<int, T>();             _keyIsObject = new Dictionary<T, int>();         }         public int IndexOf(T item)         {             if (!_keyIsObject.ContainsKey(item)) return -1;             return _keyIsObject[item] - _firstIndex;         }         public void Insert(int index, T item)         {             // pierwszy             if (_count == 0)             {                 _keyIsIndex[0] = item;                 _keyIsObject[item] = 0;             }             // na pocz?tek             else if (index == 0)             {                 _firstIndex--;                 _keyIsIndex[_firstIndex] = item;                 _keyIsObject[item] = _firstIndex;             }             // na koniec             else if (index == _count)             {                 _lastIndex++;                 _keyIsIndex[_lastIndex] = item;                 _keyIsObject[item] = _lastIndex;             }             // do ?rodka             else             {                 // przenumerowujemy pocz?tek                 if (index < _count / 2)                 {                     for (int i = _firstIndex; i <= _firstIndex + index; i++)                     {                         _keyIsIndex[i - 1] = _keyIsIndex[i];                         _keyIsObject[_keyIsIndex[i - 1]] = i - 1;                     }                     _firstIndex--;                 }                 // przenumerowujemy koniec                 else                 {                     for (int i = _lastIndex; i >= _firstIndex + index; i--)                     {                         _keyIsIndex[i + 1] = _keyIsIndex[i];                         _keyIsObject[_keyIsIndex[i + 1]] = i + 1;                     }                     _lastIndex++;                 }                 _keyIsIndex[_firstIndex + index] = item;                 _keyIsObject[item] = _firstIndex + index;             }             _count++;         }         public void RemoveAt(int index)         {             // ostatni             if (_count == 1)             {                 _keyIsIndex.Clear();                 _keyIsObject.Clear();                 _firstIndex = _lastIndex = 0;             }             // z pocz?tku             if (index == 0)             {                 _keyIsObject.Remove(_keyIsIndex[_firstIndex]);                 _keyIsIndex.Remove(_firstIndex);                 _firstIndex++;             }             // z ko?ca             else if (index == _count)             {                 _keyIsObject.Remove(_keyIsIndex[_lastIndex]);                 _keyIsIndex.Remove(_lastIndex);                 _lastIndex--;             }             // ze ?rodka             else             {                 _keyIsObject.Remove(_keyIsIndex[_firstIndex + index]);                 _keyIsIndex.Remove(_firstIndex + index);                 // przenumerowujemy pocz?tek                 if (index < _count / 2)                 {                     for (int i = _firstIndex + index; i > _firstIndex; i--)                     {                         _keyIsIndex[i] = _keyIsIndex[i - 1];                         _keyIsObject[_keyIsIndex[i]] = i;                     }                     _keyIsIndex.Remove(_firstIndex);                     _firstIndex++;                 }                 // przenumerowujemy koniec                 else                 {                     for (int i = _firstIndex + index; i < _lastIndex; i++)                     {                         _keyIsIndex[i] = _keyIsIndex[i + 1];                         _keyIsObject[_keyIsIndex[i]] = i;                     }                     _keyIsIndex.Remove(_lastIndex);                     _lastIndex--;                 }             }             _count--;         }         public T this[int index]         {             get             {                 return _keyIsIndex[_firstIndex + index];             }             set             {                 T oldValue = _keyIsIndex[_firstIndex + index];                 _keyIsIndex[_firstIndex + index] = value;                 _keyIsObject.Remove(oldValue);                 _keyIsObject.Add(value, _firstIndex + index);             }         }         public void Add(T item)         {             Insert(_count, item);         }         public void Clear()         {             _firstIndex = _lastIndex = _count = 0;             _keyIsIndex.Clear();             _keyIsObject.Clear();         }         public bool Contains(T item)         {             return _keyIsObject.ContainsKey(item);         }         public void CopyTo(T[] array, int arrayIndex)         {             _keyIsIndex.OrderBy(x => x.Key).Select(x => x.Value).ToList().CopyTo(array, arrayIndex);         }         public int Count         {             get { return _count; }         }         public bool IsReadOnly         {             get { return false; }         }         public bool Remove(T item)         {             int index = IndexOf(item);             if (index < 0) return false;             RemoveAt(index);             return true;         }         public IEnumerator<T> GetEnumerator()         {             for (int i = 0; i < _count; i++)             {                 yield return _keyIsIndex[_firstIndex + i];             }         }         System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator()         {             return GetEnumerator();         }     } }