7.1FXB.utils.Dictionary()

The FXB.utils.Dictionary class is a dictionary/hashtable which is extremely widely used within the MyTrader framework. For example, the FXB.Instruments collection is a dictionary, and so is each FXB.Message which is sent to an OnMessage() handler.

The dictionary's properties and methods are as follows:

Object

Description

length

Property returning the number of items in the dictionary

set(key, object)

Sets a key/value pair in the dictionary

remove(key)

Removes a key/value pair from the dictionary. (Trying to remove a non-existent key is not an error; it just silently does nothing.)

get(key)

Returns a value from the dictionary based on its key, or null if the key is not present

has(key)

Tests whether a key exists in the dictionary

is(keyOrArray)

Can take either a single key as a parameter, or an array of keys. Passing a single key is simply equivalent to has(). Passing an array means "does the dictionary contain at least one of these keys?". In other words, using is() with an array does an is-any-of test.

keys()

Returns all the keys in the dictionary as an array

values()

Returns all the values in the dictionary as an array

clear()

Empties the dictionary

forEach(fn)

Iterator. See description below.

each(fn)

Synonym of forEach()

Note that the callback from forEach() receives the key first, then the object. For example:

Framework.Instruments.forEach(function (key, instr) { console.log(key, instr.caption); });

This differs from the native Javascript Array.prototype.forEach, where the callback receives the item first.

The dictionary's forEach() is also different to standard Javascript Array.forEach() in that it allows early exit, by returning a non-null from the iteration function. For example, you can scan the dictionary and terminate at the first match, avoiding unnecessary further iteration through the dictionary:

// See if there is any object in the dictionary which has some particular value

var bHasValueWithProperty = false;

myDictionary.forEach(function (key, object) {

if (object.someProperty == someValue) {

// Set flag

bHasValueWithProperty = true;

// Exit from iteration, and avoid unnecessary further looping

return true;

}

});

Any non-null return value which terminates the iteration is passed back as the return value from forEach(). Therefore, the following is possible:

// See if there is any object in the dictionary which has some particular value.

// On return, matchingObject will contain either null or the first matching item.

var matchingObject = myDictionary.forEach(function (key, object) {

if (object.someProperty == someValue) {

// Exit from iteration, and avoid unnecessary further looping.

// The non-null value becomes the return value from the forEach().

return object;

}

});

Note: it is safe to modify the contents of the dictionary during forEach() iteration. For example:

// Create a dictionary with 10 items

var x = new FXB.utils.Dictionary();

for (var i = 1; i <= 10; i++) x.set(i, i);

// Gets called 9 times because item 3 is removed on the first pass (where k = 1)

x.forEach (function (k, v) {

if (x.has(3)) x.remove(3); // Remove item 3 on first iteration

});