Tuesday, June 19, 2007

Sorted Hashtable

Need an HashTable uh? Tired of that messy foreach statement ? Here's a simple implementation of a Dictionary collection, but sortable.

namespace snippets101.Collections
{
public enum sortType
{
NoSort = 1,
Keys = 2,
Values = 3
}
public class sHash
{
private ArrayList _alVals;
private ArrayList _alKeys;
private sortType _sort;

public sHash()
{

_alKeys = new ArrayList();
_alVals = new ArrayList();

_sort = sortType.NoSort;

}

public sortType SortType
{
get { return _sort; }
set { _sort = value; }

}

public void Sort()
{
Array k = _alKeys.ToArray(typeof(object));
Array v = _alVals.ToArray(typeof(object));

if (_sort == sortType.Keys)
Array.Sort(k, v, new sHashComparer());
if (_sort == sortType.Values)
Array.Sort(v, k, new sHashComparer());

_alKeys = ArrayList.Adapter(k);
_alVals = ArrayList.Adapter(v);

}

public void Add(object key, object value)
{
if (_alKeys.Contains(key))
throw new Exception("Key already present.");

_alKeys.Add(key);
_alVals.Add(value);

}

public void Clear()
{
_alKeys.Clear();
_alVals.Clear();
}

public bool Contains(object key)
{
return _alKeys.Contains(key);
}

public IDictionaryEnumerator GetEnumerator()
{
return new sHashDictionaryEnumerator(_alKeys, _alVals);
}

public bool IsFixedSize
{
get { return false; }
}

public bool IsReadOnly
{
get { return false; }
}

public ArrayList Keys
{
get { return _alKeys; }
}

public ArrayList Values
{
get { return _alVals; }
}

public void Remove(object key)
{
_alVals.RemoveAt(_alKeys.IndexOf(key));
_alKeys.Remove(key);
}

public object this[object key]
{
get
{
return _alVals[_alKeys.IndexOf(key)];
}
set
{
if (_alKeys.Contains(key))
{
_alVals[_alKeys.IndexOf(key)] = value;
}
else
{
_alKeys.Add(key);
_alVals.Add(value);
}
}
}

public int Count
{
get { return _alKeys.Count; }
}

private class sHashDictionaryEnumerator : IDictionaryEnumerator
{
DictionaryEntry[] items;
Int32 index = -1;

public sHashDictionaryEnumerator(ArrayList keys, ArrayList mappings)
{
items = new DictionaryEntry[keys.Count];
for (int i = 0; i <> {
items[i] = new DictionaryEntry(keys[i],mappings[i]);
}
}

public Object Current { get { ValidateIndex(); return items[index]; } }

public DictionaryEntry Entry
{
get { return (DictionaryEntry)Current; }
}

public Object Key { get { ValidateIndex(); return items[index].Key; } }

public Object Value { get { ValidateIndex(); return items[index].Value; } }

public Boolean MoveNext()
{
if (index < style="color: rgb(51, 51, 255);"> return true; }
return false;
}

private void ValidateIndex()
{
if (index <>= items.Length)
throw new InvalidOperationException("Enumerator is before or after the collection.");
}

public void Reset()
{
index = -1;
}
}

private class sHashComparer : IComparer
{
private bool isNumeric(Type t)
{
switch (t.Name.ToLower())
{
case "int32":
return true;
case "single":
return true;
case "double":
return true;
default:
return false;
}
}


public int Compare(object x, object y)
{

if ((isNumeric(x.GetType())) && (isNumeric(y.GetType())))
{
double d = Math.Truncate(Convert.ToSingle(x) - Convert.ToSingle(y));
if (d <>
return -1;
if (d == 0)
return 0;
if (d > 0)
return 1;

return 0;
}
if ((isNumeric(x.GetType())) && (!isNumeric(y.GetType())))
return -1;
if ((!isNumeric(x.GetType())) && (isNumeric(y.GetType())))
return 1;

return String.Compare(x.ToString(), y.ToString());
}


}


}
}

No comments: