Skip to content

Instantly share code, notes, and snippets.

@gerardpaapu
Created September 13, 2012 03:37
Show Gist options
  • Save gerardpaapu/3711689 to your computer and use it in GitHub Desktop.
Save gerardpaapu/3711689 to your computer and use it in GitHub Desktop.
;;; OrderedSet
;;; ----------
;;;
;;; A Collection class that wraps an Array.
;;; It maintains immutability, an order, and
;;; does not contain duplicates
;;;
;;; Items of the Ordered Set should implement 'Ord'
(class OrderedSet
(constructor (items ordered distinct)
(set! this.items (or items #[]))
;; ensure the qualities of the ordered set in this.items
;; call uniquify! unless the items are known to be distinct
;; call sort! unless the items are known to be sorted
(if distinct.isFalse? (this uniquify!)
ordered.isFalse? (this sort!)))
(method (contains? needle)
(this.items contains? needle))
(method (asArray)
;; return a clone so that clients don't
;; mutate our internal array
this.items.cloneArray)
(method (slice a b)
(this.items slice a, b))
(method (nth i)
this.items.[i])
(method (length)
this.items.length)
(method (concat ls)
(let (;; ls can be an OrderedSet or an Array
(items (if (ls isAn OrderedSet) ls.items
(ls isAn Array) ls))
;; items that don't exist in the destination
(new-items (ls filter ^(this contains #0) this)))
;; return the same OrderedSet unless there are new items
(if new-items.isEmpty?
this
(OrderedSet new (this.items concat new-items) true))))
(method (sort!)
;; Ensure that this.items is sorted by the Ord generics
(this.items sort ^(if (#0 > #1) MORE
(#1 < #0) LESS
EQUAL)))
(method (uniqify!)
;; Ensure that this.items is distinct
(set! this.items
(this.items reduce ^[out, item] (if (out contains? item)
out
(out concat item))
#[]))))
[
{
"type": "list",
"value": [
{
"type": "symbol",
"value": "class"
},
{
"type": "symbol",
"value": "OrderedSet"
},
{
"type": "list",
"value": [
{
"type": "symbol",
"value": "constructor"
},
{
"type": "list",
"value": [
{
"type": "symbol",
"value": "items"
},
{
"type": "symbol",
"value": "ordered"
},
{
"type": "symbol",
"value": "distinct"
}
]
},
{
"type": "list",
"value": [
{
"type": "symbol",
"value": "set!"
},
{
"type": "dot-accessor",
"root": {
"type": "symbol",
"value": "this"
},
"key": {
"type": "atom",
"value": "items"
}
},
{
"type": "list",
"value": [
{
"type": "symbol",
"value": "or"
},
{
"type": "symbol",
"value": "items"
},
{
"type": "array-literal",
"value": []
}
]
}
]
},
{
"type": "list",
"value": [
{
"type": "symbol",
"value": "if"
},
{
"type": "dot-accessor",
"root": {
"type": "symbol",
"value": "distinct"
},
"key": {
"type": "atom",
"value": "isFalse?"
}
},
{
"type": "list",
"value": [
{
"type": "symbol",
"value": "this"
},
{
"type": "symbol",
"value": "uniquify!"
}
]
},
{
"type": "dot-accessor",
"root": {
"type": "symbol",
"value": "ordered"
},
"key": {
"type": "atom",
"value": "isFalse?"
}
},
{
"type": "list",
"value": [
{
"type": "symbol",
"value": "this"
},
{
"type": "symbol",
"value": "sort!"
}
]
}
]
}
]
},
{
"type": "list",
"value": [
{
"type": "symbol",
"value": "method"
},
{
"type": "list",
"value": [
{
"type": "symbol",
"value": "contains?"
},
{
"type": "symbol",
"value": "needle"
}
]
},
{
"type": "list",
"value": [
{
"type": "dot-accessor",
"root": {
"type": "symbol",
"value": "this"
},
"key": {
"type": "atom",
"value": "items"
}
},
{
"type": "symbol",
"value": "contains?"
},
{
"type": "symbol",
"value": "needle"
}
]
}
]
},
{
"type": "list",
"value": [
{
"type": "symbol",
"value": "method"
},
{
"type": "list",
"value": [
{
"type": "symbol",
"value": "asArray"
}
]
},
{
"type": "dot-accessor",
"root": {
"type": "dot-accessor",
"root": {
"type": "symbol",
"value": "this"
},
"key": {
"type": "atom",
"value": "items"
}
},
"key": {
"type": "atom",
"value": "cloneArray"
}
}
]
},
{
"type": "list",
"value": [
{
"type": "symbol",
"value": "method"
},
{
"type": "list",
"value": [
{
"type": "symbol",
"value": "slice"
},
{
"type": "symbol",
"value": "a"
},
{
"type": "symbol",
"value": "b"
}
]
},
{
"type": "list",
"value": [
{
"type": "dot-accessor",
"root": {
"type": "symbol",
"value": "this"
},
"key": {
"type": "atom",
"value": "items"
}
},
{
"type": "symbol",
"value": "slice"
},
{
"type": "symbol",
"value": "a"
},
{
"type": "symbol",
"value": "b"
}
]
}
]
},
{
"type": "list",
"value": [
{
"type": "symbol",
"value": "method"
},
{
"type": "list",
"value": [
{
"type": "symbol",
"value": "nth"
},
{
"type": "symbol",
"value": "i"
}
]
},
{
"type": "dot-accessor",
"root": {
"type": "dot-accessor",
"root": {
"type": "symbol",
"value": "this"
},
"key": {
"type": "atom",
"value": "items"
}
},
"key": {
"type": "symbol",
"value": "i"
}
}
]
},
{
"type": "list",
"value": [
{
"type": "symbol",
"value": "method"
},
{
"type": "list",
"value": [
{
"type": "symbol",
"value": "length"
}
]
},
{
"type": "dot-accessor",
"root": {
"type": "dot-accessor",
"root": {
"type": "symbol",
"value": "this"
},
"key": {
"type": "atom",
"value": "items"
}
},
"key": {
"type": "atom",
"value": "length"
}
}
]
},
{
"type": "list",
"value": [
{
"type": "symbol",
"value": "method"
},
{
"type": "list",
"value": [
{
"type": "symbol",
"value": "concat"
},
{
"type": "symbol",
"value": "ls"
}
]
},
{
"type": "list",
"value": [
{
"type": "symbol",
"value": "let"
},
{
"type": "list",
"value": [
{
"type": "list",
"value": [
{
"type": "symbol",
"value": "items"
},
{
"type": "list",
"value": [
{
"type": "symbol",
"value": "if"
},
{
"type": "list",
"value": [
{
"type": "symbol",
"value": "ls"
},
{
"type": "symbol",
"value": "isAn"
},
{
"type": "symbol",
"value": "OrderedSet"
}
]
},
{
"type": "dot-accessor",
"root": {
"type": "symbol",
"value": "ls"
},
"key": {
"type": "atom",
"value": "items"
}
},
{
"type": "list",
"value": [
{
"type": "symbol",
"value": "ls"
},
{
"type": "symbol",
"value": "isAn"
},
{
"type": "symbol",
"value": "Array"
}
]
},
{
"type": "symbol",
"value": "ls"
}
]
}
]
},
{
"type": "list",
"value": [
{
"type": "symbol",
"value": "new-items"
},
{
"type": "list",
"value": [
{
"type": "symbol",
"value": "ls"
},
{
"type": "symbol",
"value": "filter"
},
{
"type": "list",
"value": [
{
"type": "symbol",
"value": "function"
},
{
"type": "list",
"value": []
},
{
"type": "list",
"value": [
{
"type": "symbol",
"value": "this"
},
{
"type": "symbol",
"value": "contains"
},
{
"type": "positional-argument",
"value": 0
}
]
}
]
},
{
"type": "symbol",
"value": "this"
}
]
}
]
}
]
},
{
"type": "list",
"value": [
{
"type": "symbol",
"value": "if"
},
{
"type": "dot-accessor",
"root": {
"type": "symbol",
"value": "new-items"
},
"key": {
"type": "atom",
"value": "isEmpty?"
}
},
{
"type": "symbol",
"value": "this"
},
{
"type": "list",
"value": [
{
"type": "symbol",
"value": "OrderedSet"
},
{
"type": "symbol",
"value": "new"
},
{
"type": "list",
"value": [
{
"type": "dot-accessor",
"root": {
"type": "symbol",
"value": "this"
},
"key": {
"type": "atom",
"value": "items"
}
},
{
"type": "symbol",
"value": "concat"
},
{
"type": "symbol",
"value": "new-items"
}
]
},
{
"type": "symbol",
"value": "true"
}
]
}
]
}
]
}
]
},
{
"type": "list",
"value": [
{
"type": "symbol",
"value": "method"
},
{
"type": "list",
"value": [
{
"type": "symbol",
"value": "sort!"
}
]
},
{
"type": "list",
"value": [
{
"type": "dot-accessor",
"root": {
"type": "symbol",
"value": "this"
},
"key": {
"type": "atom",
"value": "items"
}
},
{
"type": "symbol",
"value": "sort"
},
{
"type": "list",
"value": [
{
"type": "symbol",
"value": "function"
},
{
"type": "list",
"value": []
},
{
"type": "list",
"value": [
{
"type": "symbol",
"value": "if"
},
{
"type": "list",
"value": [
{
"type": "positional-argument",
"value": 0
},
{
"type": "symbol",
"value": ">"
},
{
"type": "positional-argument",
"value": 1
}
]
},
{
"type": "symbol",
"value": "MORE"
},
{
"type": "list",
"value": [
{
"type": "positional-argument",
"value": 1
},
{
"type": "symbol",
"value": "<"
},
{
"type": "positional-argument",
"value": 0
}
]
},
{
"type": "symbol",
"value": "LESS"
},
{
"type": "symbol",
"value": "EQUAL"
}
]
}
]
}
]
}
]
},
{
"type": "list",
"value": [
{
"type": "symbol",
"value": "method"
},
{
"type": "list",
"value": [
{
"type": "symbol",
"value": "uniqify!"
}
]
},
{
"type": "list",
"value": [
{
"type": "symbol",
"value": "set!"
},
{
"type": "dot-accessor",
"root": {
"type": "symbol",
"value": "this"
},
"key": {
"type": "atom",
"value": "items"
}
},
{
"type": "list",
"value": [
{
"type": "dot-accessor",
"root": {
"type": "symbol",
"value": "this"
},
"key": {
"type": "atom",
"value": "items"
}
},
{
"type": "symbol",
"value": "reduce"
},
{
"type": "list",
"value": [
{
"type": "symbol",
"value": "function"
},
{
"type": "list",
"value": [
{
"type": "symbol",
"value": "out"
},
{
"type": "symbol",
"value": "item"
}
]
},
{
"type": "list",
"value": [
{
"type": "symbol",
"value": "if"
},
{
"type": "list",
"value": [
{
"type": "symbol",
"value": "out"
},
{
"type": "symbol",
"value": "contains?"
},
{
"type": "symbol",
"value": "item"
}
]
},
{
"type": "symbol",
"value": "out"
},
{
"type": "list",
"value": [
{
"type": "symbol",
"value": "out"
},
{
"type": "symbol",
"value": "concat"
},
{
"type": "symbol",
"value": "item"
}
]
}
]
}
]
},
{
"type": "array-literal",
"value": []
}
]
}
]
}
]
}
]
}
]
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment