Key/Value Pairs : Part Two
In part one of this post I showed the slightly sluggish but typically acceptable Key/Value pairs.
But if we are willing to forgo Internet Explorer compatibility, there is a newer JavaScript feature called Map. It is supported on all modern computer and mobile browsers, and it can speed up Key/Values while adding new capabilties, the ability for the value to be an EWB class (or a string, integer or function).
Here’s what the JavaScript would look like (using strings as the values in this example):
const map1 = new Map();
map1.set('0', 'foo');
map1.set(1, 'bar');
map1.set('dog','cat')
console.log(map1.get( 'dog'));
// expected output: "cat"
const iterator1 = map1.values();
console.log(iterator1.next().value);
// Expected output: "foo"
console.log(iterator1.next().value);
// Expected output: "bar"
Creating an EWB version looks like this to set/get and iterate through the list.
procedure TestMap;
var
map1 : TJavaScriptMap;
iterator1 : TIterator;
i : integer;
begin
map1 := TJavaScriptMap.Create;
map1.set('0', 'foo');
map1.set('1', 'bar');
map1.set('dog','cat');
output( 'Size of array : ' + IntToStr( map1.Size ));
output(map1.get( 'dog'));
// expected output: "cat"
if isie then begin
output('Skipping iterator, IE does not implement it');
end else begin
output('Here is the complete list of names')
iterator1 := map1.values();
for i := 0 to map1.size - 1 do
output(iterator1.next.value );
end;
map1.Free;
end;
Running through the same tests as in the previous post, the Map construct is many times faster. What took seconds now takes about a millisecond.
But more importantly, you can set and get EWB classes since variants can hold anything.
You will need the code that implements Tmap. Those who have purchased my Nice Toolkit will find it’s in the current release. But here it is if you don’t have my toolkit:
unit nicemap;
interface
uses webcore, webdom;
type
external TIterator = class( TExternalObject )
public
property Entries : array of variant read write;
property value : variant read ;
function next : TIterator;
end;
external TInternalMap = class (TExternalObject )
public
property size : integer read;
procedure set( name : string; value : variant );
function get( name : string ) : variant;
function values : TIterator; // iterator
end;
TJavaScriptMap = class( TOBject )
private
internalmap : TInternalMap;
public
constructor create ;
destructor destroy;
function get( name : string ):variant;
procedure set( name : string ; value : variant );
function values : TIterator;
function size: integer;
end;
implementation
constructor TJavaScriptMap.create;
begin
internalmap := TInternalMap(CreateObject('new Map()'));
end;
destructor TJavaScriptMap.destroy;
begin
internalmap.free;
end;
function TJavaScriptMap.size:integer;
begin
result := internalmap.size;
end;
procedure TJavaScriptMap.Set( name : string ; value : variant );
begin
internalmap.set( name, value );
end;
function TJavaScriptMap.Get( name : string ):variant;
begin
result := internalmap.get( name );
end;
function TJavaScriptMap.values : TIterator;
begin
result := internalmap.values;
end;
end.