how would I go about removing all circular references inside of an object? For example,
let certainObject = { abc: 'test' }
certainObject.prop = certainObject
removeCircular(certainObject)
would bee
{ abc: 'test' }
how would I go about removing all circular references inside of an object? For example,
let certainObject = { abc: 'test' }
certainObject.prop = certainObject
removeCircular(certainObject)
would bee
{ abc: 'test' }
Share
Improve this question
edited Feb 7, 2021 at 20:28
ToastOnAStick
asked Feb 7, 2021 at 18:30
ToastOnAStickToastOnAStick
333 silver badges7 bronze badges
4 Answers
Reset to default 4You need to iterate through the object, while keeping track of which objects you've already seen.
function removeCircular(obj) {
const seen = new Map();
const recurse = obj => {
seen.add(obj,true);
for( let [k, v] of Object.entries(obj)) {
if( typeof v !== "object") continue;
if(seen.has(v)) delete obj[k];
else recurse(v);
}
}
recurse(obj);
}
Note that this modifies the object in-place. If you want to keep the original object, you'll need to clone it first.
I would say something like:
function removeCircular(ref) {
for (let i in ref) {
if (ref[i] === ref) delete(ref[i]);
else if (typeof ref[i] == 'Object') removeCircular(ref[i]);
}
}
Or do you want this to work recursively? - edit, it is now recursive. However, this code could potentially end up in a loop. So the code of @NiettheDarkAbsol is better.
However, your example is not circular. You assign this to property, which is effectively the window object. If you want to have a circular object, you have to do:
certainObject = { abc: 'test' };
certainObject.propery = certainObject;
With such an example, my code works.
Just adding an updated version of Niet's answer that worked for me. And also because I can't ment/reply to Markus Knappen Johansson's question. :-P
The difference is using seen.set
instead of seen.add
. I'm guessing that .add
is from another language?
function removeCircular(obj) {
const seen = new Map();
const recurse = obj => {
seen.set(obj, true);
Object.entries(obj).forEach(([k, v]) => {
if (typeof v !== 'object') return;
if (seen.has(v)) delete obj[k];
else recurse(v);
});
};
recurse(obj);
}
var prams = {
name: 'abc',
obj : this,
val : 'hello ',
}
function removecyclic(obj){
newobj = {};
for(key in obj){
if(typeof obj[key] == 'object'){
if(!obj.hasOwnProperty(key)){
newobj[key] = obj[key];
}
}
else{
newobj[key] = obj[key];
}
}
return newobj;
}
console.log(removecyclic(prams));