<snapdata remixID="10166178"><project name="hashtable3" app="Snap! 6, https://snap.berkeley.edu" version="1"><notes></notes><thumbnail>data:image/png;base64,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</thumbnail><stage name="Stage" width="480" height="360" costume="0" color="255,255,255,1" tempo="60" threadsafe="false" penlog="false" volume="100" pan="0" lines="round" ternary="false" hyperops="true" codify="false" inheritance="true" sublistIDs="false" scheduled="false" id="1"><pentrails>data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAeAAAAFoCAYAAACPNyggAAAOhUlEQVR4Xu3VwQkAAAjEMN1/abewn7jAQRC64wgQIECAAIF3gX1fNEiAAAECBAiMAHsCAgQIECAQCAhwgG6SAAECBAgIsB8gQIAAAQKBgAAH6CYJECBAgIAA+wECBAgQIBAICHCAbpIAAQIECAiwHyBAgAABAoGAAAfoJgkQIECAgAD7AQIECBAgEAgIcIBukgABAgQICLAfIECAAAECgYAAB+gmCRAgQICAAPsBAgQIECAQCAhwgG6SAAECBAgIsB8gQIAAAQKBgAAH6CYJECBAgIAA+wECBAgQIBAICHCAbpIAAQIECAiwHyBAgAABAoGAAAfoJgkQIECAgAD7AQIECBAgEAgIcIBukgABAgQICLAfIECAAAECgYAAB+gmCRAgQICAAPsBAgQIECAQCAhwgG6SAAECBAgIsB8gQIAAAQKBgAAH6CYJECBAgIAA+wECBAgQIBAICHCAbpIAAQIECAiwHyBAgAABAoGAAAfoJgkQIECAgAD7AQIECBAgEAgIcIBukgABAgQICLAfIECAAAECgYAAB+gmCRAgQICAAPsBAgQIECAQCAhwgG6SAAECBAgIsB8gQIAAAQKBgAAH6CYJECBAgIAA+wECBAgQIBAICHCAbpIAAQIECAiwHyBAgAABAoGAAAfoJgkQIECAgAD7AQIECBAgEAgIcIBukgABAgQICLAfIECAAAECgYAAB+gmCRAgQICAAPsBAgQIECAQCAhwgG6SAAECBAgIsB8gQIAAAQKBgAAH6CYJECBAgIAA+wECBAgQIBAICHCAbpIAAQIECAiwHyBAgAABAoGAAAfoJgkQIECAgAD7AQIECBAgEAgIcIBukgABAgQICLAfIECAAAECgYAAB+gmCRAgQICAAPsBAgQIECAQCAhwgG6SAAECBAgIsB8gQIAAAQKBgAAH6CYJECBAgIAA+wECBAgQIBAICHCAbpIAAQIECAiwHyBAgAABAoGAAAfoJgkQIECAgAD7AQIECBAgEAgIcIBukgABAgQICLAfIECAAAECgYAAB+gmCRAgQICAAPsBAgQIECAQCAhwgG6SAAECBAgIsB8gQIAAAQKBgAAH6CYJECBAgIAA+wECBAgQIBAICHCAbpIAAQIECAiwHyBAgAABAoGAAAfoJgkQIECAgAD7AQIECBAgEAgIcIBukgABAgQICLAfIECAAAECgYAAB+gmCRAgQICAAPsBAgQIECAQCAhwgG6SAAECBAgIsB8gQIAAAQKBgAAH6CYJECBAgIAA+wECBAgQIBAICHCAbpIAAQIECAiwHyBAgAABAoGAAAfoJgkQIECAgAD7AQIECBAgEAgIcIBukgABAgQICLAfIECAAAECgYAAB+gmCRAgQICAAPsBAgQIECAQCAhwgG6SAAECBAgIsB8gQIAAAQKBgAAH6CYJECBAgIAA+wECBAgQIBAICHCAbpIAAQIECAiwHyBAgAABAoGAAAfoJgkQIECAgAD7AQIECBAgEAgIcIBukgABAgQICLAfIECAAAECgYAAB+gmCRAgQICAAPsBAgQIECAQCAhwgG6SAAECBAgIsB8gQIAAAQKBgAAH6CYJECBAgIAA+wECBAgQIBAICHCAbpIAAQIECAiwHyBAgAABAoGAAAfoJgkQIECAgAD7AQIECBAgEAgIcIBukgABAgQICLAfIECAAAECgYAAB+gmCRAgQICAAPsBAgQIECAQCAhwgG6SAAECBAgIsB8gQIAAAQKBgAAH6CYJECBAgIAA+wECBAgQIBAICHCAbpIAAQIECAiwHyBAgAABAoGAAAfoJgkQIECAgAD7AQIECBAgEAgIcIBukgABAgQICLAfIECAAAECgYAAB+gmCRAgQICAAPsBAgQIECAQCAhwgG6SAAECBAgIsB8gQIAAAQKBgAAH6CYJECBAgIAA+wECBAgQIBAICHCAbpIAAQIECAiwHyBAgAABAoGAAAfoJgkQIECAgAD7AQIECBAgEAgIcIBukgABAgQICLAfIECAAAECgYAAB+gmCRAgQICAAPsBAgQIECAQCAhwgG6SAAECBAgIsB8gQIAAAQKBgAAH6CYJECBAgIAA+wECBAgQIBAICHCAbpIAAQIECAiwHyBAgAABAoGAAAfoJgkQIECAgAD7AQIECBAgEAgIcIBukgABAgQICLAfIECAAAECgYAAB+gmCRAgQICAAPsBAgQIECAQCAhwgG6SAAECBAgIsB8gQIAAAQKBgAAH6CYJECBAgIAA+wECBAgQIBAICHCAbpIAAQIECAiwHyBAgAABAoGAAAfoJgkQIECAgAD7AQIECBAgEAgIcIBukgABAgQICLAfIECAAAECgYAAB+gmCRAgQICAAPsBAgQIECAQCAhwgG6SAAECBAgIsB8gQIAAAQKBgAAH6CYJECBAgIAA+wECBAgQIBAICHCAbpIAAQIECAiwHyBAgAABAoGAAAfoJgkQIECAgAD7AQIECBAgEAgIcIBukgABAgQICLAfIECAAAECgYAAB+gmCRAgQICAAPsBAgQIECAQCAhwgG6SAAECBAgIsB8gQIAAAQKBgAAH6CYJECBAgIAA+wECBAgQIBAICHCAbpIAAQIECAiwHyBAgAABAoGAAAfoJgkQIECAgAD7AQIECBAgEAgIcIBukgABAgQICLAfIECAAAECgYAAB+gmCRAgQICAAPsBAgQIECAQCAhwgG6SAAECBAgIsB8gQIAAAQKBgAAH6CYJECBAgIAA+wECBAgQIBAICHCAbpIAAQIECAiwHyBAgAABAoGAAAfoJgkQIECAgAD7AQIECBAgEAgIcIBukgABAgQICLAfIECAAAECgYAAB+gmCRAgQICAAPsBAgQIECAQCAhwgG6SAAECBAgIsB8gQIAAAQKBgAAH6CYJECBAgIAA+wECBAgQIBAICHCAbpIAAQIECAiwHyBAgAABAoGAAAfoJgkQIECAgAD7AQIECBAgEAgIcIBukgABAgQICLAfIECAAAECgYAAB+gmCRAgQICAAPsBAgQIECAQCAhwgG6SAAECBAgIsB8gQIAAAQKBgAAH6CYJECBAgIAA+wECBAgQIBAICHCAbpIAAQIECAiwHyBAgAABAoGAAAfoJgkQIECAgAD7AQIECBAgEAgIcIBukgABAgQICLAfIECAAAECgYAAB+gmCRAgQICAAPsBAgQIECAQCAhwgG6SAAECBAgIsB8gQIAAAQKBgAAH6CYJECBAgIAA+wECBAgQIBAICHCAbpIAAQIECAiwHyBAgAABAoGAAAfoJgkQIECAgAD7AQIECBAgEAgIcIBukgABAgQICLAfIECAAAECgYAAB+gmCRAgQICAAPsBAgQIECAQCAhwgG6SAAECBAgIsB8gQIAAAQKBgAAH6CYJECBAgIAA+wECBAgQIBAICHCAbpIAAQIECAiwHyBAgAABAoGAAAfoJgkQIECAgAD7AQIECBAgEAgIcIBukgABAgQICLAfIECAAAECgYAAB+gmCRAgQICAAPsBAgQIECAQCAhwgG6SAAECBAgIsB8gQIAAAQKBgAAH6CYJECBAgIAA+wECBAgQIBAICHCAbpIAAQIECAiwHyBAgAABAoGAAAfoJgkQIECAgAD7AQIECBAgEAgIcIBukgABAgQICLAfIECAAAECgYAAB+gmCRAgQICAAPsBAgQIECAQCAhwgG6SAAECBAgIsB8gQIAAAQKBgAAH6CYJECBAgIAA+wECBAgQIBAICHCAbpIAAQIECAiwHyBAgAABAoGAAAfoJgkQIECAgAD7AQIECBAgEAgIcIBukgABAgQICLAfIECAAAECgYAAB+gmCRAgQICAAPsBAgQIECAQCAhwgG6SAAECBAgIsB8gQIAAAQKBgAAH6CYJECBAgIAA+wECBAgQIBAICHCAbpIAAQIECAiwHyBAgAABAoGAAAfoJgkQIECAgAD7AQIECBAgEAgIcIBukgABAgQICLAfIECAAAECgYAAB+gmCRAgQICAAPsBAgQIECAQCAhwgG6SAAECBAgIsB8gQIAAAQKBgAAH6CYJECBAgIAA+wECBAgQIBAICHCAbpIAAQIECAiwHyBAgAABAoGAAAfoJgkQIECAgAD7AQIECBAgEAgIcIBukgABAgQICLAfIECAAAECgYAAB+gmCRAgQICAAPsBAgQIECAQCAhwgG6SAAECBAgIsB8gQIAAAQKBgAAH6CYJECBAgIAA+wECBAgQIBAICHCAbpIAAQIECAiwHyBAgAABAoGAAAfoJgkQIECAgAD7AQIECBAgEAgIcIBukgABAgQICLAfIECAAAECgYAAB+gmCRAgQICAAPsBAgQIECAQCAhwgG6SAAECBAgIsB8gQIAAAQKBgAAH6CYJECBAgIAA+wECBAgQIBAICHCAbpIAAQIECAiwHyBAgAABAoGAAAfoJgkQIECAgAD7AQIECBAgEAgIcIBukgABAgQICLAfIECAAAECgYAAB+gmCRAgQICAAPsBAgQIECAQCAhwgG6SAAECBAgIsB8gQIAAAQKBgAAH6CYJECBAgIAA+wECBAgQIBAICHCAbpIAAQIECAiwHyBAgAABAoGAAAfoJgkQIECAgAD7AQIECBAgEAgIcIBukgABAgQICLAfIECAAAECgYAAB+gmCRAgQICAAPsBAgQIECAQCAhwgG6SAAECBAgIsB8gQIAAAQKBgAAH6CYJECBAgIAA+wECBAgQIBAICHCAbpIAAQIECAiwHyBAgAABAoGAAAfoJgkQIECAgAD7AQIECBAgEAgIcIBukgABAgQICLAfIECAAAECgYAAB+gmCRAgQICAAPsBAgQIECAQCAhwgG6SAAECBAgIsB8gQIAAAQKBgAAH6CYJECBAgIAA+wECBAgQIBAICHCAbpIAAQIECAiwHyBAgAABAoGAAAfoJgkQIECAgAD7AQIECBAgEAgIcIBukgABAgQIHLFxAWmhEwHPAAAAAElFTkSuQmCC</pentrails><costumes><list struct="atomic" id="2"></list></costumes><sounds><list struct="atomic" id="3"></list></sounds><variables></variables><blocks></blocks><scripts></scripts><sprites><sprite name="key" idx="1" x="0" y="0" heading="90" scale="1" volume="100" pan="0" rotation="1" draggable="true" costume="0" color="80,80,80,1" pen="tip" id="8"><costumes><list struct="atomic" id="9"></list></costumes><sounds><list struct="atomic" id="10"></list></sounds><blocks></blocks><variables></variables><scripts><script x="19.999999999999996" y="16.66666666666666"><block s="receiveGo"></block><block s="doSetVar"><l>my dict</l><custom-block s="empty dictionary"></custom-block></block><custom-block s="add { %s : %s } to %l"><l>CSC110</l><block s="reportNewList"><list><l>Monday</l><l>Wednesday</l></list></block><block var="my dict"/></custom-block><custom-block s="add { %s : %s } to %l"><l>ECE200</l><block s="reportNewList"><list><l>Friday</l></list></block><block var="my dict"/></custom-block><custom-block s="add { %s : %s } to %l"><l>MUS301</l><block s="reportNewList"><list><l>Tuesday</l><l>Thursday</l></list></block><block var="my dict"/></custom-block><block s="doForEach"><l>item</l><custom-block s="keys of %l"><block var="my dict"/></custom-block><script><block s="doIf"><block s="reportListContainsItem"><custom-block s="value at %s of %l"><block var="item"/><block var="my dict"/></custom-block><l>Friday</l></block><script><custom-block s="remove key-value pair at %s of %l"><block var="item"/><block var="my dict"/></custom-block></script></block></script></block><block s="doSayFor"><block var="my dict"/><l>2</l></block></script></scripts></sprite><watcher var="my dict" style="normal" x="10" y="10" color="243,118,29"/></sprites></stage><hidden></hidden><headers></headers><code></code><blocks><block-definition s="empty dictionary" type="reporter" category="other"><comment x="0" y="0" w="171" collapsed="false">Creates a hashtable. Your code must contain one of these in order to use hashtables. (hashtable variables are always transient)</comment><header></header><code></code><translations></translations><inputs></inputs><script><block s="doReport"><block s="evaluate"><block s="reportJSFunction"><list></list><l>var stage = this.parentThatIsA(StageMorph);&#xD;if (!stage.supportsHashtable) {&#xD;    stage.supportsHashtable = true;&#xD;    var oldSnapEquals = snapEquals;&#xD;    snapEquals = function(a, b) {&#xD;        if ((a instanceof Hashtable) || (b instanceof Hashtable)) {&#xD;            if ((a instanceof Hashtable) &amp;&amp; (b instanceof Hashtable)) {&#xD;                return a.equalTo(b);&#xD;            }&#xD;            return false;&#xD;        }&#xD;        return oldSnapEquals(a, b);&#xD;    };&#xD;    var oldTypeOf = Process.prototype.reportTypeOf;&#xD;    Process.prototype.reportTypeOf = function(object) {&#xD;        if (object instanceof Hashtable) {&#xD;            return &apos;hashtable&apos;;&#xD;        }&#xD;        return oldTypeOf(object);&#xD;    };&#xD;    var oldDataAsMorph = SpriteBubbleMorph.prototype.dataAsMorph;&#xD;    SpriteBubbleMorph.prototype.dataAsMorph = function(data, toggle) {&#xD;        if (data instanceof Hashtable) {&#xD;            return oldDataAsMorph(data.asString(), toggle);&#xD;        } else {&#xD;            return oldDataAsMorph(data, toggle);&#xD;        }&#xD;    };&#xD;    var oldDrawNew = CellMorph.prototype.drawNew;&#xD;    CellMorph.prototype.drawNew = function(toggle, type) {&#xD;        var hash = this.contents instanceof Hashtable;&#xD;        var original;&#xD;        if (hash) {&#xD;            original = this.contents;&#xD;            this.contents = this.contents.asString();&#xD;        }&#xD;        oldDrawNew.call(this, toggle, type);&#xD;        if (hash) {&#xD;            this.contents = original;&#xD;        }&#xD;    };&#xD;    window.Hashtable = function() {&#xD;        this.obj = {};&#xD;        this.isImmutable = false; // if it&apos;s a key&#xD;        this.changed();&#xD;    };&#xD;    Hashtable.prototype.hash = function(object) {&#xD;        var type = typeof(object);&#xD;        if (object === null || type !== &apos;object&apos;) {&#xD;            return String(object);&#xD;        }&#xD;        else if (object instanceof Context) {&#xD;            return this.hashContext(object.expression).join(&apos;&apos;);&#xD;        }&#xD;        else if (object instanceof List) {&#xD;            return this.hashList(object).join(&apos;&apos;);&#xD;        }&#xD;        else if (object instanceof Hashtable) {&#xD;            return this.hashHashtable(object);&#xD;        }&#xD;        else {&#xD;            throw new Error(&apos;unable to hash &apos; + object)&#xD;        } &#xD;    };&#xD;    Hashtable.prototype.hashContext = function(expression, start) {&#xD;        start = start || [];&#xD;        var selector = expression.selector === &apos;reportGetVar&apos; ?&#xD;            expression.blockSpec :&#xD;            expression.selector;&#xD;        start.push(selector);&#xD;        for (var i = 0; i &lt; expression.children.length; i++) {&#xD;            start.push(String.fromCharCode(i + 32));&#xD;            if (expression.children[i].selector !== undefined) {&#xD;                this.hashContext(expression.children[i], start);&#xD;                // pushes to start, ignore return value&#xD;            }&#xD;        }&#xD;        return start;&#xD;    };&#xD;    Hashtable.prototype.hashList = function(list, start) {&#xD;        start = start || [];&#xD;        var expand = function(data, index, table) {&#xD;            start.push(String.fromCharCode(i + 32));&#xD;            start.push(table.hash(data));&#xD;        };&#xD;        var index = 0;&#xD;        while (list.isLinked) {&#xD;            list.isImmutable = true;&#xD;            expand(list.first, index, this);&#xD;            index ++;&#xD;            list = list.rest;&#xD;        }&#xD;        list.isImmutable = true&#xD;        for (var i = 0; i &lt; list.contents.length; i++) {&#xD;            expand(list.contents[i], index + i, this);&#xD;        }&#xD;        return start;&#xD;    };&#xD;    Hashtable.prototype.hashHashtable = function (table) {&#xD;        if (table === this) {&#xD;            throw new Error(&apos;hashtable cannot be its own key&apos;);&#xD;        }&#xD;        table.isImmutable = true;&#xD;        var data = [];&#xD;        var index;&#xD;        for (let [hashkey, value] of Object.entries(table.obj)) {&#xD;            for (index = 0; index &lt; value.length; index ++) {&#xD;                data.push(String.fromCharCode(index + 32))&#xD;                data.push(hashkey);&#xD;                // equal to this.hash(value[index][0])&#xD;                data.push(&apos;!&apos;)&#xD;                data.push(this.hash(value[index][1]));&#xD;            }&#xD;        }&#xD;        return data.join(&apos;&apos;);&#xD;    };&#xD;    Hashtable.prototype.asString = function() {&#xD;        data = [&apos;{&apos;]&#xD;        var index;&#xD;        for (let [hashkey, value] of Object.entries(this.obj)) {&#xD;            for (index = 0; index &lt; value.length; index ++) {&#xD;                data.push(String(value[index][0]));&#xD;                data.push(&apos;:&apos;);&#xD;                data.push(String(value[index][1]));&#xD;                data.push(&apos;,&apos;);&#xD;            }&#xD;        }&#xD;        data[data.length-1] = &apos;}&apos;;&#xD;        return data.join(&apos;&apos;);&#xD;    };&#xD;    Hashtable.prototype.get = function(key) {&#xD;        var hash = this.hash(key);&#xD;        var list = this.obj[hash];&#xD;        if (list === undefined) {return null;}&#xD;        // no undefined allowed in snap&#xD;        for (var i = 0; i &lt; list.length; i++) {&#xD;            // in case of collision&#xD;            if (snapEquals(key, list[i][0])) {&#xD;                return list[i][1];&#xD;            }&#xD;        }&#xD;        return null;&#xD;    };&#xD;    Hashtable.prototype.set = function(key, value) {&#xD;        this.changed();&#xD;        var hash = this.hash(key);&#xD;        var list = this.obj[hash];&#xD;        if (list === undefined) {&#xD;            this.obj[hash] = [];&#xD;            list = this.obj[hash];&#xD;        }&#xD;        for (var i = 0; i &lt; list.length; i++) {&#xD;            if (snapEquals(key, list[i][0])) {&#xD;                list[i][1] = value;&#xD;                return;&#xD;            }&#xD;        }&#xD;        list.push([key, value]); // new&#xD;    };&#xD;    Hashtable.prototype.remove = function(key) {&#xD;        this.changed();&#xD;        var hash = this.hash(key);&#xD;        var list = this.obj[hash];&#xD;        if (list === undefined) {&#xD;            list = [];&#xD;        }&#xD;        for (var i = 0; i &lt; list.length; i++) {&#xD;            if (snapEquals(key, list[i][0])) {&#xD;                list.splice(i, 1);&#xD;                if (list.length === 0) {&#xD;                    delete this.obj[hash];&#xD;                }&#xD;                return;&#xD;            }&#xD;        }&#xD;    };&#xD;    Hashtable.prototype.clear = function() {&#xD;        this.changed();&#xD;        this.obj = {};&#xD;    };&#xD;    Hashtable.prototype.foreach = function(map) {&#xD;        var index;&#xD;        for (let [hashkey, value] of Object.entries(this.obj)) {&#xD;            for (index = 0; index &lt; value.length; index++){&#xD;                map(value[index][0], value[index][1]);&#xD;            }&#xD;        }&#xD;    };&#xD;    Hashtable.prototype.equalTo = function(other) {&#xD;        var hashkey;&#xD;        for (hashkey of other.obj) {&#xD;            if (!Object.prototype.hasOwnProperty.call(this.obj, hashkey)) {&#xD;                return false;&#xD;            }&#xD;        }&#xD;        try {&#xD;            this.foreach(function(key, value) {&#xD;                if (value !== other.get(key)) {&#xD;                    throw new Error();&#xD;                }&#xD;            });&#xD;            return true;&#xD;        } catch(e) {&#xD;            return false;&#xD;        }&#xD;    };&#xD;    Hashtable.prototype.changed = function() {&#xD;        if (this.isImmutable) {throw new Error(&apos;cannot edit hashtable that is key&apos;);}&#xD;        this.lastChanged = Date.now();&#xD;    };&#xD;    List.prototype.changed = function() {&#xD;        if (this.isImmutable) {throw new Error(&apos;cannot edit list that is key&apos;);}&#xD;        this.lastChanged = Date.now();&#xD;    };&#xD;}&#xD;return new Hashtable();&#xD;</l></block><list></list></block></block></script></block-definition><block-definition s="value at %&apos;key&apos; of %&apos;hashtable&apos;" type="reporter" category="other"><comment x="0" y="0" w="133" collapsed="false">Finds a value in a hashtable. Constant time.</comment><header></header><code></code><translations></translations><inputs><input type="%s"></input><input type="%l"></input></inputs><script><block s="doReport"><block s="evaluate"><block s="reportJSFunction"><list><l>key</l><l>hashtable</l><l>process</l></list><l>process.assertType(hashtable, &apos;hashtable&apos;);&#xD;return hashtable.get(key);</l></block><list><block var="key"/><block var="hashtable"/></list></block></block></script></block-definition><block-definition s="replace value at %&apos;key&apos; of %&apos;hashtable&apos; with %&apos;value&apos;" type="command" category="other"><comment x="0" y="0" w="119" collapsed="false">Replaces or adds a value. Constant time.</comment><header></header><code></code><translations></translations><inputs><input type="%s"></input><input type="%l"></input><input type="%s"></input></inputs><script><block s="doRun"><block s="reportJSFunction"><list><l>key</l><l>hashtable</l><l>value</l><l>process</l></list><l>process.assertType(hashtable, &apos;hashtable&apos;);&#xD;hashtable.set(key, value)</l></block><list><block var="key"/><block var="hashtable"/><block var="value"/></list></block></script></block-definition><block-definition s="remove key-value pair at %&apos;key&apos; of %&apos;hashtable&apos;" type="command" category="other"><comment x="0" y="0" w="190" collapsed="false">Removes a key. No effect if the key was not there to start with. Constant time.</comment><header></header><code></code><translations></translations><inputs><input type="%s"></input><input type="%l"></input></inputs><script><block s="doRun"><block s="reportJSFunction"><list><l>key</l><l>hashtable</l><l>process</l></list><l>process.assertType(hashtable, &apos;hashtable&apos;);&#xD;hashtable.remove(key);</l></block><list><block var="key"/><block var="hashtable"/></list></block></script></block-definition><block-definition s="clear %&apos;hashtable&apos;" type="command" category="other"><comment x="0" y="0" w="202" collapsed="false">Removes all keys. Leaves hashtable just like a newly constructed one. Constant time.</comment><header></header><code></code><translations></translations><inputs><input type="%l"></input></inputs><script><block s="doRun"><block s="reportJSFunction"><list><l>hashtable</l><l>process</l></list><l>process.assertType(hashtable, &apos;hashtable&apos;);&#xD;hashtable.clear();</l></block><list><block var="hashtable"/></list></block></script></block-definition><block-definition s="%&apos;hashtable&apos; contains %&apos;key&apos;" type="predicate" category="other"><comment x="0" y="0" w="191.99999999999997" collapsed="false">Checks if there is a value attached to a key. Good for set usage. Constant time. Identical to keys contains, but faster.</comment><header></header><code></code><translations></translations><inputs><input type="%l"></input><input type="%s"></input></inputs><script><block s="doReport"><block s="evaluate"><block s="reportJSFunction"><list><l>key</l><l>hashtable</l><l>process</l></list><l>process.assertType(hashtable, &apos;hashtable&apos;);&#xD;return hashtable.get(key) !== null;</l></block><list><block var="key"/><block var="hashtable"/></list></block></block></script></block-definition><block-definition s="keys of %&apos;hashtable&apos;" type="reporter" category="other"><comment x="0" y="0" w="127" collapsed="false">Finds all keys present in a hashtable. Linear time.</comment><header></header><code></code><translations></translations><inputs><input type="%l"></input></inputs><script><block s="doReport"><block s="evaluate"><block s="reportJSFunction"><list><l>hashtable</l><l>process</l></list><l>process.assertType(hashtable, &apos;hashtable&apos;);&#xD;var keys = [];&#xD;hashtable.foreach(function(key) {&#xD;    keys.push(key);&#xD;});&#xD;return new List(keys);</l></block><list><block var="hashtable"/></list></block></block></script></block-definition><block-definition s="number of pairs in %&apos;hashtable&apos;" type="reporter" category="other"><comment x="0" y="0" w="146" collapsed="false">Counts the number of keys from the keys block. Linear time.</comment><header></header><code></code><translations></translations><inputs><input type="%l"></input></inputs><script><block s="doReport"><block s="reportListLength"><custom-block s="keys of %l"><block var="hashtable"/></custom-block></block></block></script></block-definition><block-definition s="for each %&apos;key&apos; in %&apos;hashtable&apos; %&apos;action&apos;" type="command" category="pen"><comment x="0" y="0" w="138" collapsed="false">Loops through the keys, much like the list block. Linear time.</comment><header></header><code></code><translations></translations><inputs><input type="%upvar"></input><input type="%l"></input><input type="%ca"></input></inputs></block-definition><block-definition s="add { %&apos;key&apos; : %&apos;value&apos; } to %&apos;hashtable&apos;" type="command" category="other"><header></header><code></code><translations></translations><inputs><input type="%s"></input><input type="%s"></input><input type="%l"></input></inputs><script><block s="doRun"><block s="reportJSFunction"><list><l>key</l><l>hashtable</l><l>value</l><l>process</l></list><l>process.assertType(hashtable, &apos;hashtable&apos;);&#xD;hashtable.set(key, value)</l></block><list><block var="key"/><block var="hashtable"/><block var="value"/></list></block></script></block-definition></blocks><variables><variable name="my dict"><l>0</l></variable></variables></project><media name="hashtable3" app="Snap! 6, https://snap.berkeley.edu" version="1"></media></snapdata>