Last active
July 8, 2018 13:26
-
-
Save mtavkhelidze/913e4793cdd1fa0116786b05f55f52cf to your computer and use it in GitHub Desktop.
Ordered set data structure in JavaScript from Functional Program Design in Scala course by Martin Odersky.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
function NonEmpty(elem, left, right) { | |
const contains = (x) => { | |
if (x < elem) | |
return left.contains(x); | |
else if (x > elem) | |
return right.contains(x); | |
else if (x === elem) | |
return true; | |
else | |
throw new Error("Type mismatch"); | |
}; | |
const incl = (x) => { | |
if (x < elem) | |
return NonEmpty(elem, left.incl(x), right); | |
else if (x > elem) | |
return NonEmpty(elem, left, right.incl(x)); | |
else if (x === elem) | |
return NonEmpty(elem, left, right); | |
else | |
throw new Error("Type mismatch"); | |
}; | |
const union = (other) => left.union(right.union(other)).incl(elem); | |
const toString = () => { | |
return "(" + left + " <- " + elem + " -> " + right + ")"; | |
}; | |
const size = () => 1 + left.size() + right.size(); | |
const toArray = () => [...left.toArray(), elem, ...right.toArray()]; | |
return Object.freeze({ | |
toArray, | |
size, | |
contains, | |
incl, | |
union, | |
toString, | |
valueOf: toString, | |
}); | |
} | |
function Empty() { | |
const contains = (x) => false; | |
const incl = (x) => NonEmpty(x, Empty(), Empty()); | |
const union = (other) => other; | |
const toString = () => "Empty"; | |
const size = () => 0; | |
const toArray = () => []; | |
return Object.freeze({ | |
toArray, | |
size, | |
contains, | |
incl, | |
union, | |
toString, | |
valueOf: toString, | |
}); | |
} | |
function OrderedSet() { | |
if(arguments.length > 0) | |
return NonEmpty.apply(null, arguments); | |
else | |
return Empty(); | |
} | |
// Some testing | |
function print() { | |
const xs = [...arguments]; | |
console.log(...xs.map(String)); | |
} | |
const xs = [23772, 11512, 30699, 31552, 25500, 12025, 6860, 26078, 28311, 32684, 32684]; | |
const set = xs.reduce((set, x) => set.incl(x), OrderedSet()); | |
print("Size should be 10:", set.size()); | |
print(set); | |
const set1 = [13921, 10221, 19551, 31998, 7855].reduce((set, x) => set.incl(x), OrderedSet()); | |
print("Size should be 5:", set1.size()); | |
print(set1); | |
const set2 = set.union(set1); | |
print("New size 15:", set2.size()); | |
print(set2); | |
const xs1 = set2.toArray(); | |
print(xs1.length); | |
print(xs1); | |
// make it large | |
const set3 = Array(1000000).fill(0).map(() => Math.floor(Math.random() * 1000000)).reduce((set, x) => set.incl(x), OrderedSet()); | |
print(set3.size()); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment