using System;
using System.Collections;
using System.Collections.Generic;
namespace Vanara.Collections
{
/// A sparse array based on a dictionary.
public class SparseArray : IList
{
/// Base hash table
protected readonly Dictionary hashtable;
/// Initializes a new instance of the class.
public SparseArray()
{
hashtable = new Dictionary();
}
/// Returns an enumerator that iterates through the collection.
/// A that can be used to iterate through the collection.
public IEnumerator GetEnumerator() => hashtable.Values.GetEnumerator();
/// Determines whether the array contains the specified value.
/// The value.
/// true if the array contains the specified value; otherwise, false.
public bool Contains(T item) => hashtable.ContainsValue(item);
/// Removes all items from the .
/// The is read-only.
public void Clear()
{
hashtable.Clear();
}
/// Gets the index of the specified item, or returns -1 if item is not in the array.
/// The item.
///
public int IndexOf(T item)
{
foreach (var hash in hashtable)
{
if (hash.Value.Equals(item))
return hash.Key;
}
return -1;
}
IEnumerator IEnumerable.GetEnumerator() => GetEnumerator();
/// Inserts an item to the at the specified index.
/// The zero-based index at which should be inserted.
/// The object to insert into the .
/// is not a valid index in the .
/// The is read-only.
public void Insert(int index, T item)
{
if (hashtable.ContainsKey(index))
hashtable[index] = item;
else
hashtable.Add(index, item);
}
/// Removes the item at the specified index.
/// The zero-based index of the item to remove.
/// is not a valid index in the .
/// The is read-only.
public void RemoveAt(int index)
{
hashtable.Remove(index);
}
/// Gets or sets the element at the specified index.
/// The index of the element.
/// The element at the specified index.
public T this[int index]
{
get => hashtable.TryGetValue(index, out T ret) ? ret : default;
set => Insert(index, value);
}
/// Adds an item to the .
/// The object to add to the .
/// The is read-only.
void ICollection.Add(T item)
{
throw new NotSupportedException();
}
///
/// Copies the elements of the to an , starting at a particular index.
///
///
/// The one-dimensional that is the destination of the elements copied from . The must have zero-based indexing.
///
/// The zero-based index in at which copying begins.
/// is null.
/// is less than 0.
///
/// is multidimensional.-or- is equal to or greater than the length of .-or-The number of elements in the source is greater than the available space
/// from to the end of the destination .-or-Type T cannot be cast automatically to the type
/// of the destination .
///
public void CopyTo(T[] array, int arrayIndex)
{
hashtable.Values.CopyTo(array, arrayIndex);
}
/// Gets the number of elements contained in the .
/// The number of elements contained in the .
public int Count => hashtable.Count;
/// Gets a value indicating whether the is read-only.
/// true if the is read-only; otherwise, false.
public bool IsReadOnly => false;
/// Removes the first occurrence of a specific object from the .
/// The object to remove from the .
///
/// true if was successfully removed from the ; otherwise, false. This
/// method also returns false if is not found in the original .
///
/// The is read-only.
public bool Remove(T item)
{
var idx = IndexOf(item);
if (idx == -1)
return false;
RemoveAt(idx);
return true;
}
/// Collapses array into new, condensed array. Does not maintain indexes.
/// An array of
public T[] ToArray()
{
var output = new T[hashtable.Values.Count];
hashtable.Values.CopyTo(output, 0);
return output;
}
}
}