util/Collection.js

/* eslint-disable jsdoc/reject-function-type, jsdoc/reject-any-type */
/**
 * An extended Map with utility methods.
 * @class Collection
 */
class Collection extends Map {
  /**
   * Finds first matching value by property or function.
   * Same as `Array#find`.
   * @param {string|Function} propOrFunc - Property or function to test.
   * @param {any} [value] - Value to find.
   * @returns {any|null} - The found item or null if none found.
   */
  find (propOrFunc, value) {
    if (typeof propOrFunc === 'string') {
      if (value === undefined) {
        return null
      }

      for (const item of this.values()) {
        if (item[propOrFunc] === value) {
          return item
        }
      }

      return null
    }

    if (typeof propOrFunc === 'function') {
      let i = 0
      for (const item of this.values()) {
        if (propOrFunc(item, i, this)) {
          return item
        }
        i++
      }

      return null
    }

    return null
  }

  /**
   * Filters cache by function.
   * Same as `Array#filter`.
   * @param {Function} func - Function to test.
   * @param {any} [thisArg] - The context for the function.
   * @returns {Collection} - A new collection with the filtered items.
   */
  filter (func, thisArg) {
    if (thisArg) {
      func = func.bind(thisArg)
    }

    const results = new this.constructor()

    let i = 0
    for (const [key, item] of this) {
      if (func(item, i, this)) {
        results.set(key, item)
      }
      i++
    }

    return results
  }

  /**
   * Maps cache by function.
   * Same as `Array#map`.
   * @param {Function} func - Function to use.
   * @param {any} [thisArg] - The context for the function.
   * @returns {any[]} - An array with the mapped items.
   */
  map (func, thisArg) {
    if (thisArg) {
      func = func.bind(thisArg)
    }

    const array = new Array(this.size)

    let i = 0
    for (const item of this.values()) {
      array[i] = func(item, i, this)
      i++
    }

    return array
  }
}

export default Collection