Paranoia
Erfahrenes Mitglied
Hallo zusammen
Ich habe vor langer Zeit mit Hilfe des Interfaces IEnumerator eine eigene "Listen-Klasse" programmiert. Es war damals eigentlich eher ein Spielerei. Doch mittlerweile ist diese Klasse in einigen Projekten im Einsatz. Grundsätzlich funktioniert auch alles einwandfrei. Jetzt muss ich diese Klasse aber mit einer Sortierung erweitern und irgendwie herrscht da in meinem Kopf ziemliche Leere zu diesem Thema
Ich weiss, dass es heute viel bessere und simplere Ansätze für eine solche Liste gibt, nur wie gesagt, ist sie halt bereits in produktivem Einsatz.
Kann mir jemand einen Tipp geben, wie ich in untenstehendem Source Code eine Sortierung anbringen kann (z. B. dass ich IComparable einsetzen kann)? Die Sortierung sollte nicht auf den Key sondern auf die Values angewandt werden. Ich wäre auch offen, die Klasse komplett zu überarbeiten (vereinfachen), wenn danach dieselbe Funktionalität gewährleistet ist.
Für eure Hilfestellungen bedanke ich mich bereits im Voraus.
Grüsse
Paranoia
Ich habe vor langer Zeit mit Hilfe des Interfaces IEnumerator eine eigene "Listen-Klasse" programmiert. Es war damals eigentlich eher ein Spielerei. Doch mittlerweile ist diese Klasse in einigen Projekten im Einsatz. Grundsätzlich funktioniert auch alles einwandfrei. Jetzt muss ich diese Klasse aber mit einer Sortierung erweitern und irgendwie herrscht da in meinem Kopf ziemliche Leere zu diesem Thema
Ich weiss, dass es heute viel bessere und simplere Ansätze für eine solche Liste gibt, nur wie gesagt, ist sie halt bereits in produktivem Einsatz.
Kann mir jemand einen Tipp geben, wie ich in untenstehendem Source Code eine Sortierung anbringen kann (z. B. dass ich IComparable einsetzen kann)? Die Sortierung sollte nicht auf den Key sondern auf die Values angewandt werden. Ich wäre auch offen, die Klasse komplett zu überarbeiten (vereinfachen), wenn danach dieselbe Funktionalität gewährleistet ist.
Code:
public class ObjectIterator : IEnumerable
{
private const short MINIMUM_SIZE = 16;
private const short MINIMUM_GROW = 4;
private string[] _keys;
private object[] _values;
private int _size;
private int _capacity;
public ObjectIterator()
{
_keys = new string[MINIMUM_SIZE];
_values = new object[MINIMUM_SIZE];
_size = 0;
_capacity = 0;
}
public int Count
{
get { return _size; }
}
public ICollection Keys
{
get
{
Array newKeys = null;
copyTo(ref newKeys, 0);
return newKeys;
}
}
public ICollection Values
{
get
{
Array newValues = null;
copyTo(_values, ref newValues, 0);
return newValues;
}
}
public object this [string key]
{
set
{
if (value == null)
{
throw new Exception("null values are not allowed!");
}
int position = getPositionByKey(key);
if (position < 0)
{
throw new Exception(string.Format("key '{0}' does not exist!", key));
}
_values[position] = value;
}
get { return get(key); }
}
public void add(string key, object value)
{
if (key == null)
{
throw new Exception("key must not be null!");
}
if (getPositionByKey(key) >= 0)
{
throw new Exception("key already exists!");
}
if (_size == _keys.Length)
{
int newCapacity = _keys.Length * 2;
if (newCapacity < _keys.Length + MINIMUM_GROW)
{
newCapacity = _keys.Length + MINIMUM_GROW;
}
setCapacity(newCapacity);
}
_keys[_capacity] = key;
_values[_capacity] = value;
_capacity = (_capacity + 1) % _keys.Length;
_size++;
}
public object get(string key)
{
int position = getPositionByKey(key);
if (position < 0)
{
throw new Exception(string.Format("no value for key '{0}' found!", key));
}
return _values[position];
}
public void clear()
{
if (_capacity > 0)
{
Array.Clear(_keys, 0, _size);
Array.Clear(_values, 0, _size);
}
else
{
Array.Clear(_keys, 0, _keys.Length);
Array.Clear(_keys, 0, _capacity);
Array.Clear(_values, 0, _values.Length);
Array.Clear(_values, 0, _capacity);
}
_capacity = 0;
_size = 0;
}
public bool containsKey(string key)
{
return getPositionByKey(key) >= 0;
}
public bool containsObject(object obj)
{
return getPositionByValue(obj) >= 0;
}
public void remove(string key)
{
if (getPositionByKey(key) < 0)
{
throw new Exception(string.Format("key '{0}' does not exist!", key));
}
string[] newKeys = new string[_keys.Length];
object[] newValues = new object[_values.Length];
int remove = 0;
for (int i = 0; i < _capacity; i++)
{
if (_keys[i].CompareTo(key) == 0)
{
remove++;
continue;
}
newKeys[i - remove] = _keys[i];
newValues[i - remove] = _values[i];
}
_keys = newKeys;
_values = newValues;
_capacity = (_capacity - 1) % _keys.Length;
_size--;
}
public void remove(object obj)
{
if (getPositionByValue(obj) < 0)
{
throw new Exception("object does not exist!");
}
string[] newKeys = new string[_keys.Length];
object[] newValues = new object[_values.Length];
int remove = 0;
for (int i = 0; i < _capacity; i++)
{
if (_values[i].Equals(obj))
{
remove++;
continue;
}
newKeys[i - remove] = _keys[i];
newValues[i - remove] = _values[i];
}
_keys = newKeys;
_values = newValues;
_capacity = (_capacity - 1) % _keys.Length;
_size--;
}
public void copyTo(ref Array array, Int32 index)
{
copyTo(_keys, ref array, index);
}
private void copyTo(Array source, ref Array destination, Int32 index)
{
if (_capacity == 0)
{
// zero length array
destination = Array.CreateInstance((new object()).GetType(), _size);
}
if (destination == null)
{
destination = Array.CreateInstance(source.GetValue(0).GetType(), _size);
}
if (destination.Length < _size)
{
throw new Exception("array size is to small for copying!");
}
Array.Copy(source, index, destination, index, _size - index);
}
public IEnumerator GetEnumerator()
{
return new ObjectIteratorEnumerator(this);
}
private void setCapacity(int capacity)
{
string[] newKeys = new String[capacity];
object[] newValues = new object[capacity];
if (_size > 0)
{
if (_capacity > 0)
{
Array.Copy(_keys, 0, newKeys, 0, _size);
Array.Copy(_values, 0, newValues, 0, _size);
}
else
{
Array.Copy(_keys, 0, newKeys, 0, _keys.Length);
Array.Copy(_keys, 0, newKeys, _keys.Length, _capacity);
Array.Copy(_values, 0, newValues, 0, _values.Length);
Array.Copy(_values, 0, newValues, _values.Length, _capacity);
}
}
_keys = newKeys;
_values = newValues;
_capacity = _size;
}
// 0..* = key found
// -1 = key not found
private int getPositionByKey(string key)
{
for (int i = 0; i < _keys.Length; i++)
{
if (_keys[i] == null)
{
continue;
}
int j = _keys[i].CompareTo(key);
if (_keys[i].CompareTo(key) == 0)
{
return i;
}
}
return -1;
}
// 0..* = key found
// -1 = key not found
private int getPositionByValue(object value)
{
for (int i = 0; i < _values.Length; i++)
{
if (_values[i] == null)
{
continue;
}
if (_values[i].Equals(value))
{
return i;
}
}
return -1;
}
internal Object GetElement(int i)
{
return _keys[i % _keys.Length];
}
class ObjectIteratorEnumerator : IEnumerator
{
private ObjectIterator _o;
private int _index;
private Object currentElement;
internal ObjectIteratorEnumerator(ObjectIterator o)
{
_o = o;
_index = 0;
currentElement = _o._keys;
if (_o._size == 0)
_index = -1;
}
public virtual bool MoveNext()
{
if (_index < 0)
{
currentElement = _o._keys;
return false;
}
currentElement = _o.GetElement(_index);
_index++;
if (_index == _o._size)
_index = -1;
return true;
}
public virtual void Reset()
{
if (_o._size == 0)
_index = -1;
else
_index = 0;
currentElement = _o._keys;
}
public virtual Object Current
{
get
{
if (currentElement == _o._keys)
{
if (_index == 0)
throw new InvalidOperationException("Invalid Operation");
else
throw new InvalidOperationException("Invalid operation");
}
return currentElement;
}
}
}
}
Für eure Hilfestellungen bedanke ich mich bereits im Voraus.
Grüsse
Paranoia