function createSet() {
    var items = {}; // map from hash to array of objects/values
    var count = 0;

    /**
     * Get the number of elements in the set.
     */
    function size() {
        return count;
    }

    /**
     * Return true if there the given value is in the set or false if not.
     */
    function has(value) {
        var candidates = items[hash(value)];

        if (!candidates) {
            return false;
        }

        for (var i = candidates.length - 1; i >= 0; i--) {
            if (value === candidates[i]) {
                return true;
            }
        }

        return false;
    }

    /**
     * Add the given value to the set. Returns true if this operation
     * actually changed the set (that is, true if the item wasn't already
     * in the set).
     */
    function add(value) {
        var h = hash(value);
        var candidates = items[h];

        if (!candidates) {
            candidates = items[h] = [];
        }

        for (var i = candidates.length - 1; i >= 0; i--) {
            if (value === candidates[i]) {
                return false; // Already in set.
            }
        }

        candidates.push(value);
        count++;
        return true;
    }

    /**
     * Remove the given value from the set. Returns true if this operation
     * actually changed the set (that is, true if the item in fact was in
     * the set to begin with).
     */
    function remove(value) {
        var candidates = items[hash(value)];

        if (!candidates) {
            return false; // Not present in set.
        }

        for (var i = candidates.length - 1; i >= 0; i--) {
            if (value === candidates[i]) {
                candidates.splice(i, 1);
                count--;
                return true;
            }
        }

        return false; // Not present in set.
    }

    /**
     * Call the given callback on each element. The callback is called
     * with a single argument (the element). There is no guarantee
     * about the order of callbacks.
     */
    function forEach(callback) {
        Object.keys(items).forEach(forHash);

        function forHash(hash) {
            items[hash].forEach(callback);
        }
    }

    return {
        add:     add,
        forEach: forEach,
        has:     has,
        remove:  remove,
        size:    size
    };
}
/**
 * Construct a set (unordered list of objects) keyed by object/value
 * identity.
 */
Construct a set (unordered list of objects) keyed by object/value
identity.
Construct a set ( unordered list of objects ) keyed by object / value identity .
function createSet() {
    var items = {}; 
    var count = 0;
    function size() {
        return count;
    }
    function has(value) {
        var candidates = items[hash(value)];
        if (!candidates) {
            return false;
        }
        for (var i = candidates.length - 1; i >= 0; i--) {
            if (value === candidates[i]) {
                return true;
            }
        }
        return false;
    }
    function add(value) {
        var h = hash(value);
        var candidates = items[h];
        if (!candidates) {
            candidates = items[h] = [];
        }
        for (var i = candidates.length - 1; i >= 0; i--) {
            if (value === candidates[i]) {
                return false; 
            }
        }
        candidates.push(value);
        count++;
        return true;
    }
    function remove(value) {
        var candidates = items[hash(value)];
        if (!candidates) {
            return false; 
        }
        for (var i = candidates.length - 1; i >= 0; i--) {
            if (value === candidates[i]) {
                candidates.splice(i, 1);
                count--;
                return true;
            }
        }
        return false; 
    }
    function forEach(callback) {
        Object.keys(items).forEach(forHash);
        function forHash(hash) {
            items[hash].forEach(callback);
        }
    }
    return {
        add:     add,
        forEach: forEach,
        has:     has,
        remove:  remove,
        size:    size
    };
}
function createSet ( ) { var items = { } ; var count = 0 ; function size ( ) { return count ; } function has ( value ) { var candidates = items [ hash ( value ) ] ; if ( ! candidates ) { return false ; } for ( var i = candidates . length - 1 ; i >= 0 ; i -- ) { if ( value === candidates [ i ] ) { return true ; } } return false ; } function add ( value ) { var h = hash ( value ) ; var candidates = items [ h ] ; if ( ! candidates ) { candidates = items [ h ] = [ ] ; } for ( var i = candidates . length - 1 ; i >= 0 ; i -- ) { if ( value === candidates [ i ] ) { return false ; } } candidates . push ( value ) ; count ++ ; return true ; } function remove ( value ) { var candidates = items [ hash ( value ) ] ; if ( ! candidates ) { return false ; } for ( var i = candidates . length - 1 ; i >= 0 ; i -- ) { if ( value === candidates [ i ] ) { candidates . splice ( i , 1 ) ; count -- ; return true ; } } return false ; } function forEach ( callback ) { Object . keys ( items ) . forEach ( forHash ) ; function forHash ( hash ) { items [ hash ] . forEach ( callback ) ; } } return { add : add , forEach : forEach , has : has , remove : remove , size : size } ; }
Construct a set (unordered list of objects) keyed by object/value
 identity.
Construct a set ( unordered list of objects ) keyed by object / value identity .
// map from hash to array of objects/values /**
     * Get the number of elements in the set.
     */ /**
     * Return true if there the given value is in the set or false if not.
     */ /**
     * Add the given value to the set. Returns true if this operation
     * actually changed the set (that is, true if the item wasn't already
     * in the set).
     */ // Already in set. /**
     * Remove the given value from the set. Returns true if this operation
     * actually changed the set (that is, true if the item in fact was in
     * the set to begin with).
     */ // Not present in set. // Not present in set. /**
     * Call the given callback on each element. The callback is called
     * with a single argument (the element). There is no guarantee
     * about the order of callbacks.
     */