I've been playing with the new ES6 Map(), just to get used to it, and, now we can get the size, it occurred to me that one could efficiently take random samples of a map, to see what it looked like.
Clearly it is possible to iterate through, make an Array of all entries, and then choose random samples. But this is unattractive for large maps.
There is some code at the end which achieves this by exploiting the newly-available size of the map. It is slightly more efficient than copying, but still unattractive.
But the Map method keys() returns an iterator object, whose next() method we normally use to iterate over a Map instance. And, it also includes an array of all the entries. This is shown in the following summary of the Chrome Devtools output:
coinNames.keys()
MapIterator
"keys"
....
[[Entries]]
:
Array[7]
0
:
30
1
:
12
... (entries omitted)
length
:
7
I could not find out how to access this array, so as to locate an entry by the array index.
The (rather pointless, but illustrative) code below works (given get_random_integer() and report()...).
The function play() is invoked on a button press, and logs a random name.
But, it would be nice not to iterate, and just get the entry at a given position in the array.
Any ideas?
function CoinName(name, slang, plural) {
this.name = name;
this.plural = plural;
}
const coinNames = new Map();
window.onload = init;
function init() {
report ('OK');
var button = document.getElementById('buttonA');
button.addEventListener('click', play);
coinNames.set(30, new CoinName('half crown'));
coinNames.set(12, new CoinName('shilling', 'bob'));
coinNames.set(3, new CoinName('threepenny bit'));
coinNames.set(6, new CoinName('sixpence', 'tanner'));
coinNames.set(1, new CoinName('penny', '', 'pence'));
coinNames.set(1/4, new CoinName('farthing'));
coinNames.set(1/2, new CoinName('halfpenny', 'hapeny',
'halfpence'));
}
function getRandomKey() {
let requiredIndex = get_random_integer(0, coinNames.size);
let keys = coinNames.keys();
let found = undefined;
let goon = true;
let i = 0;
while(goon) {
goon = keys.next().value;
//report(goon);
if(goon && i===requiredIndex) {
found = goon;
goon = false;
}
i += 1;
}
return found;
}
function play() {
let key = getRandomKey();
let entry = coinNames.get(key);
report(entry.name);
}