Learn more  » Push, build, and install  RubyGems npm packages Python packages Maven artifacts PHP packages Go Modules Bower components Debian packages RPM packages NuGet packages

skava / exotic-structures   js

Repository URL to install this package:

Version: 2.0.4 

/ wip / OrderedHashMap.compat.ddd

/*jshint browserify: true, es3: true */

module.exports = OrderedHashMap
function OrderedHashMap() {
  this._values = {}
  this._keys = {}
  this._order = []
  this._id = Date.now() + '$' + String(Math.random()).slice(2)
  this._nextId = 0
}
OrderedHashMap.from = function(arr, keyProp) {
  var Ctor = this
  var m = new Ctor()
  for (var i = 0; i < arr.length; i++) {
    var value = arr[i]
    var key = keyProp
      ? typeof keyProp === 'function'
        ? keyProp(value, i, arr)
        : value[keyProp]
      : i
    var hash = m._hash(key)
    m._order.push(hash)
    m._keys[hash] = key
    m._values[hash] = value
  }
  return m
}
OrderedHashMap.fromTuples = function(arr) {
  var Ctor = this
  var m = new Ctor()
  for (var i = 0; i < arr.length; i++) {
    var item = arr[i]
    var key = item[0]
    var hash = m._hash(key)
    m._order.push(hash)
    m._keys[hash] = item[0]
    m._values[hash] = item[1]
  }
  return m
}
OrderedHashMap.prototype._hash = function(key) {
  var t = typeof key
  if (key === null || key === undefined || t === 'boolean' || t === 'number')
    return '%' + key
  if (t === 'string') return '"' + key
  if (t !== 'object' && t !== 'function') return '?' + key
  if (key instanceof Date) return '@' + Number(key)
  if (key instanceof RegExp) return '!' + key
  var h = '__hash$' + this._id
  if (key[h] === undefined) {
    Object.defineProperty(key, h, this._nextId)
    this._nextId += 1
  }
  return '#' + key[h]
}
OrderedHashMap.prototype.count = function() {
  return this._order.length
}
OrderedHashMap.prototype.keyAt = function(i) {
  if (i < 0 || i > this._order.length) return undefined
  return this._keys[this._order[i]]
}
OrderedHashMap.prototype.valueAt = function(i) {
  if (i < 0 || i > this._order.length) return undefined
  return this._values[this._order[i]]
}
OrderedHashMap.prototype.indexOf = function(key) {
  var hash = this._hash(key)
  return this._order.indexOf(hash)
}
OrderedHashMap.prototype.insert = function(index, key, value) {
  var hash = this._hash(key)
  var i = this._order.indexOf(hash)
  if (i !== -1) this._order.splice(i, 1)
  if (index >= this._order.length) this._order.push(hash)
  else if (index < 0) this._order.unshift(hash)
  else this._order.splice(index, 0, hash)
  this._keys[hash] = key
  this._values[hash] = value
}
OrderedHashMap.prototype.set = function(key, value) {
  var hash = this._hash(key)
  var i = this._order.indexOf(hash)
  if (i === -1) this._order.push(hash)
  this._keys[hash] = key
  this._values[hash] = value
}
OrderedHashMap.prototype.get = function(key) {
  var hash = this._hash(key)
  return this._values[hash]
}
OrderedHashMap.prototype.remove = function(key) {
  var hash = this._hash(key)
  var i = this._order.indexOf(hash)
  if (i === -1) return false
  this._order.splice(i, 1)
  delete this._keys[hash]
  delete this._values[hash]
  return true
}
OrderedHashMap.prototype.unshift = function(key, value) {
  var hash = this._hash(key)
  var i = this._order.indexOf(hash)
  if (i !== -1) this._order.splice(i, 1)
  this._order.unshift(hash)
  this._keys[hash] = key
  this._values[hash] = value
}
OrderedHashMap.prototype.shift = function() {
  if (!this._order.length) return undefined
  var hash = this._order.shift()
  var key = this._keys[hash]
  var value = this._values[hash]
  delete this._keys[hash]
  delete this._values[hash]
  return [key, value]
}
OrderedHashMap.prototype.push = function(key, value) {
  var hash = this._hash(key)
  var i = this._order.indexOf(hash)
  if (i !== -1) this._order.splice(i, 1)
  this._order.push(hash)
  this._keys[hash] = key
  this._values[hash] = value
}
OrderedHashMap.prototype.pop = function() {
  if (!this._order.length) return undefined
  var hash = this._order.pop()
  var key = this._keys[hash]
  var value = this._values[hash]
  delete this._keys[hash]
  delete this._values[hash]
  return [key, value]
}
OrderedHashMap.prototype.items = function() {
  var arr = []
  for (var i = 0; i < this._order.length; i++) {
    var hash = this._order[i]
    arr.push([this._keys[hash], this._values[hash]])
  }
  return arr
}
OrderedHashMap.prototype.values = function() {
  var arr = []
  for (var i = 0; i < this._order.length; i++) {
    var hash = this._order[i]
    arr.push(this._values[hash])
  }
  return arr
}
OrderedHashMap.prototype.keys = function() {
  var arr = []
  for (var i = 0; i < this._order.length; i++) {
    var hash = this._order[i]
    arr.push(this._keys[hash])
  }
  return arr
}
OrderedHashMap.prototype.forEach = function(fn) {
  for (var i = 0; i < this._order.length; i++) {
    var hash = this._order[i]
    fn(this._values[hash], this._keys[hash], i, this)
  }
}
OrderedHashMap.prototype.map = function(fn) {
  var arr = []
  for (var i = 0; i < this._order.length; i++) {
    var hash = this._order[i]
    arr.push(fn(this._values[hash], this._keys[hash], this))
  }
  return arr
}
OrderedHashMap.prototype.filter = function(fn) {
  var m = new OrderedHashMap()
  for (var i = 0; i < this._order.length; i++) {
    var hash = this._order[i]
    var key = this._keys[hash]
    var value = this._values[hash]
    if (!fn(value, key, this)) continue
    m._order.push(hash)
    m._keys[hash] = key
    m._values[hash] = value
  }
  return m
}
OrderedHashMap.prototype.reduce = function(fn, initial) {
  var i = 0
  var accu = initial
  if (accu === undefined) {
    if (!this._order.length)
      throw new TypeError('Must provide an initial value for empty maps')
    accu = this._values[this._order[0]]
    i = 1
  }
  for (; i < this._order.length; i++) {
    var hash = this._order[i]
    accu = fn(accu, this._values[hash], this._keys[hash], this)
  }
  return accu
}
OrderedHashMap.prototype.reduceRight = function(fn, initial) {
  var i = this._order.length
  var accu = initial
  if (accu === undefined) {
    if (!this._order.length)
      throw new TypeError('Must provide an initial value for empty maps')
    accu = this._values[this._order[i - 1]]
    i -= 1
  }
  for (var i = this._order.length; i > 0; i--) {
    var hash = this._order[i - 1]
    accu = fn(accu, this._values[hash], this._keys[hash], this)
  }
  return accu
}