Title: Sparse array implementation using TStringlist
Question: Sparse arrays are arrays that only uses memory for the cells that are actually in use although the full size of the array is always available. A prime example is the cells in a spreadsheet application: they can have enormous dimensions (like 99999 * 99999 cells) but still only use memory equivalent to the cells where there is any data. This article shows how you can easily create a sparse array with any number of dimensions and of arbitrary size.
Answer:
{ One solution is to create a new class (let's call it TSparseArray) that stores the data in a TStringlists Objects array and the dimensions in the Strings array as a compound string. Here's a two-dimensional example: }
interface
type
TSparseArray = class(TObject)
private
FCells:TStringlist;
function GetCell(Col,Row:integer):TObject;
procedure SetCell(Col,Row:integer;const Value:TObject);
public
constructor Create;
destructor Destroy;override;
property Cells[Col,Row:integer]:TObject read GetCell write SetCell;default;
end;
implementation
const
cFmtDims = '%d:%d';
constructor TSparseArray.Create;
begin
inherited Create;
FCells := TStringlist.Create;
FCells.Sorted := true; // faster retrieval, slower updates, needed for dupIgnore
FCells.Duplicates := dupIgnore;
end;
destructor TSparseArray.Destroy;
begin
FCells.Free;
inherited Destroy;
end;
function TSparseArray.GetCell(Col,Row:integer):TObject;
var i:integer;
begin
Result := nil;
i := FCells.IndexOf(Format(cFmtDims,[Col,Row]));
if i -1 then
Result := FCells.Objects[i];
end;
procedure TSparseArray.SetCell(Col,Row:integer;const Value:TObject);
begin
// dupIgnore guarantees that if this cell already exists, this will overwrite it
FCells.AddObject(Format(cFmtDims,[Col,Row]),Value);
end;
end.
{ To create a sparse array with more dimensions, you just have to redefine the Cells property (and the read / write methods) and change the format of cFmtDims accordingly. You can even mix dimensions of different types (i.e Cells[const Row:string;Col:integer]:TObject). I think you can come up with more neat things yourself. Enjoy!}