function removeDuplicates(arr, opt_rv, opt_hashFn) {
  const returnArray = opt_rv || arr;
  const defaultHashFn = function(item) {
    // Prefix each type with a single character representing the type to
    // prevent conflicting keys (e.g. true and 'true').
    return goog.isObject(item) ? 'o' + goog.getUid(item) :
                                 (typeof item).charAt(0) + item;
  };
  const hashFn = opt_hashFn || defaultHashFn;

  let cursorInsert = 0;
  let cursorRead = 0;
  const seen = {};

  while (cursorRead < arr.length) {
    const current = arr[cursorRead++];
    const key = hashFn(current);
    if (!Object.prototype.hasOwnProperty.call(seen, key)) {
      seen[key] = true;
      returnArray[cursorInsert++] = current;
    }
  }
  returnArray.length = cursorInsert;
}
Removes all duplicates from an array (retaining only the first
occurrence of each array element).  This function modifies the
array in place and doesn't change the order of the non-duplicate items.

For objects, duplicates are identified as having the same unique ID as
defined by {@link goog.getUid}.

Alternatively you can specify a custom hash function that returns a unique
value for each item in the array it should consider unique.

Runtime: N,
Worstcase space: 2N (no dupes)

@param {IArrayLike<T>} arr The array from which to remove
    duplicates.
@param {Array=} opt_rv An optional array in which to return the results,
    instead of performing the removal inplace.  If specified, the original
    array will remain unchanged.
@param {function(T):string=} opt_hashFn An optional function to use to
    apply to every item in the array. This function should return a unique
    value for each item in the array it should consider unique.
@template T