A very simple solution which I just made is this:
public class Sparse3DMatrix<T>
{
Dictionary<Tuple<int,int,int>, T> values = new Dictionary<Tuple<int, int, int>, T>();
public T this[int x, int y, int z]
{
get { return values[new Tuple<int, int, int>(x, y, z)]; }
set { values[new Tuple<int, int, int>(x, y, z)] = value; }
}
public bool ContainsKey(int x, int y, int z)
{
return values.ContainsKey(new Tuple<int, int, int>(x, y, z));
}
}
usage:
var test = new Sparse3DMatrix<float>();
test[1, 1, 1] = 1f;
Console.WriteLine(test[1, 1, 1]);
It could be extended with methods like those his version have, and with checks for x, y, z
values etc.
I'm sure someone have something to say about its performance. It will be a decent implementation unless you really need something it for high-performance. It depends on the hash-code implementation of Tuple
and your specific usage. If we assume the hashes are good, we will have O(1)
lookup time. If you know you will have a lot of elements, you could use new Dictionary<...>(initial capacity)
to avoid unnecessary resizing when added items.
Unlike his, this only have a single Dictionary
with all the items. His version have dictionaries of dictionaries. The benefit of his, is if you have to scan over an entire row, you can just iterate the second-level dictionary (this will not help you is you want to scan over columns) which is faster than individual lookup of the items. But having a single dictionary means smaller memory usage - especially when you have few items per row.