@quartic/bokehjs
Version:
Interactive, novel data visualization
120 lines (93 loc) • 2.54 kB
text/coffeescript
import {difference} from "./array"
import {isEqual} from "./eq"
import {isArray} from "./types"
export class MultiDict
constructor : () ->
= {}
_existing: (key) ->
if key of
return [key]
else
return null
add_value: (key, value) ->
if value == null
throw new Error("Can't put null in this dict")
if isArray(value)
throw new Error("Can't put arrays in this dict")
existing =
if existing == null
[key] = value
else if isArray(existing)
existing.push(value)
else
[key] = [existing, value]
remove_value: (key, value) ->
existing =
if isArray(existing)
new_array = difference(existing, [value])
if new_array.length > 0
[key] = new_array
else
delete [key]
else if isEqual(existing, value)
delete [key]
get_one: (key, duplicate_error) ->
existing =
if isArray(existing)
if existing.length == 1
return existing[0]
else
throw new Error(duplicate_error)
else
return existing
export class Set
constructor: (array) ->
if not array
= []
else
if array.constructor is Set
return new Set array.values
if array.constructor is Array
= Set.compact(array)
else
= [array]
: (array) ->
newArray = []
for item in array
newArray.push item if newArray.indexOf(item) is -1
return newArray
push: (item) ->
if
.push(item)
remove: (item) ->
i = .indexOf item
= .slice(0,i).concat .slice(i+1)
length: ->
.length
includes: (item) ->
.indexOf(item) isnt -1
missing: (item) ->
not item
slice: (from, to) ->
.slice from, to
join: (str) ->
.join str
toString: ->
', '
includes: (item) ->
.indexOf(item) isnt -1
union: (set) ->
set = new Set(set)
new Set .concat set.values
intersect: (set) ->
set = new Set(set)
newSet = new Set
for item in set.values
newSet.push item if and set.includes(item)
return newSet
diff: (set) ->
set = new Set(set)
newSet = new Set
for item in
newSet.push item if set.missing(item)
return newSet