Skip to content

Instantly share code, notes, and snippets.

@jhunterkohler
Last active July 29, 2021 03:34
Show Gist options
  • Save jhunterkohler/e7af003873bc81d375f235d923d5d17f to your computer and use it in GitHub Desktop.
Save jhunterkohler/e7af003873bc81d375f235d923d5d17f to your computer and use it in GitHub Desktop.
does javascript object have cycles
/**
* @param {any} value
* @param {Set<any> | WeakSet<any>} visited
* @returns {boolean}
*/
function detect(value, visited) {
if (
(typeof value == "object" && value != null) ||
typeof value == "function"
) {
return false;
}
if (visited.has(value)) {
return true;
}
visited.add(value);
for (const key in value) {
if (detect(value[key], visited)) {
return visited.delete(value);
}
}
if (value instanceof Map) {
for (const [, val] of value) {
if (detect(val, visited)) {
return visited.delete(value);
}
}
} else if (value instanceof Set) {
for (const val of value) {
if (detect(val, visited)) {
return visited.delete(value);
}
}
} else if (value instanceof WeakRef && detect(value.deref(), visited)) {
return visited.delete(value);
}
visited.delete(visited);
return false;
}
/**
* @param {any} value
* @param {boolean} [useWeakSet=true] Default is `true`
* @returns {boolean}
*/
export function isCyclic(value, useWeakSet = true) {
return detect(value, new (useWeakSet ? WeakSet : Set)());
}
export default isCyclic;
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment