Skip to content

Instantly share code, notes, and snippets.

@nim579
Created November 12, 2021 11:15
Show Gist options
  • Save nim579/e23cf3ca16d72eb4fcd07d0d091fc251 to your computer and use it in GitHub Desktop.
Save nim579/e23cf3ca16d72eb4fcd07d0d091fc251 to your computer and use it in GitHub Desktop.
List (Object[]) with index and uniq index fields
_ = require('lodash')
reorder = (object)->
newObj = {}
Object.keys(object).sort().forEach (key)->
newObj[key] = object[key]
return newObj
uid = -> Symbol('key')
class IndexedList
constructor: (indexBy = [], uniqBy = [])->
state = new Map()
index = {}
uIndex = {}
indexBy = indexBy.map (item)-> if _.isArray item then item.sort() else [item]
uniqBy = uniqBy.sort()
Object.defineProperty @, 'indexBy', get: -> indexBy
Object.defineProperty @, 'uniqBy', get: -> uniqBy
Object.defineProperty @, 'state', get: -> state
Object.defineProperty @, 'index', get: -> index
Object.defineProperty @, 'uIndex', get: -> uIndex
Object.defineProperty @, 'items', get: -> Array.from state.values()
Object.defineProperty @, 'entries', get: -> Array.from state.entries()
Object.defineProperty @, 'size', get: -> state.size
return @
set: (object)->
key = @_uniqKey object
if key
mapKey = @uIndex[key]
@_unindex mapKey if mapKey
@uIndex[key] = mapKey = uid() unless mapKey
else
mapKey = uid()
@state.set mapKey, object
@_index object, mapKey
return @
get: (object)->
key = @_key object
if @index[key]
console.log 'index'
result = []
@index[key].forEach (mapKey)=>
result.push @state.get mapKey
return result
else
return _.filter @items, object
del: (object)->
key = @_key object
if @index[key]
result = []
@index[key].forEach (mapKey)=>
@_unindex mapKey
@state.delete mapKey
else
_.forEach @entries, ([mapKey, val])=>
if _.find [val], object
@_unindex mapKey
@state.delete mapKey
return
return @
_unindex: (mapKey)->
object = @state.get mapKey
_.forEach @indexBy, (keys)=>
key = @_key _.pick object, keys
if @index[key]
@index[key].delete mapKey
delete @index[key] if @index[key].size is 0
_index: (object, mapKey)->
return unless mapKey
_.forEach @indexBy, (keys)=>
key = @_key _.pick object, keys
@index[key] = new Set() unless @index[key]
@index[key].add mapKey
return
_key: (object)->
return null if @indexBy.length is 0
object = reorder object
return JSON.stringify object
_uniqKey: (object)->
return null if @uniqBy.length is 0
uniq = {}
_.forEach @uniqBy, (key)->
uniq[key] = object[key] or null
return
return JSON.stringify uniq
module.exports = IndexedList
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment