Business
Jobs
  • About Us
  • Solutions
    • Job Postings
      Post your job and receive qualified candidates in 48h.
    • Candidate Assessments
      500+ technical and psychological tests, plus anti-fraud.
    • Headhunting
      Tailor-made executive search from start to finish.
    • Payroll + EOR
      Payroll dispersal and EOR across 15+ LATAM countries.
  • Pricing
  • Jobs

0

196
Views
Implementing a set that treats object equality on value not reference

I want to be able to implement a Set in javascript that allows me to do something like this:

const s = Set([[1,2,3], [1,2,3], 1, 2, 1]);
s.add([1,2,3]);
console.log(s);
// {[1,2,3], 1, 2}

Of course, since the === operator is used on the set, any object will not equal itself unless a reference to the same object is passed, and so instead of the above we would currently get:

Set(5) { [ 1, 2, 3 ], [ 1, 2, 3 ], 1, 2, [ 1, 2, 3 ] }

Does the following seem like a good way to implement this? What might I be missing or can improve on?

class MySet extends Set {
    constructor(...args) {
        super();
        for (const elem of args) {
            if (!this.has(elem)) super.add(elem);
        }
    }
    has(elem) {
        if (typeof elem !== 'object') return super.has(elem);
        for (const member of this) {
            if (typeof member !== 'object') continue;
            if (JSON.stringify(member) === JSON.stringify(elem))
                return true;
        }
        return false;
    }
    add(elem) {
        return (this.has(elem)) ? this : super.add(elem);
    }
    delete(elem) {
        if (typeof elem !== 'object') return super.delete(elem);
        for (const member of this) {
            if (typeof member !== 'object') continue;
            if (JSON.stringify(member) === JSON.stringify(elem))
                return super.delete(member);
        }
        return false;
    }
}

about 4 years ago · Juan Pablo Isaza
1 answers
Answer question

0

Assuming the provided objects don't contain values that cannot be stringified to JSON (function, undefined, symbol, etc.) You can use JSON.stringify().

One problem you might encounter is that stringifying { a: 1, b: 2 } doesn't produce the same result as { b: 2, a: 1 }. A fairly easy way to solve this would be to stringify the object and make sure the resulting JSON has properties placed in alphabetical order.

For this we can look to the answer provided in sort object properties and JSON.stringify.

I also think you are over complicating things by only stringifying values if they are an object. Instead you could just stringfy everything, null would result in "null", "string" would result in '"string"', etc. This simplifies the code by a lot. The only restriction then becomes that all values must be a valid JSON value.

// see linked answer
function JSONstringifyOrder(obj, space)
{
    const allKeys = new Set();
    JSON.stringify(obj, (key, value) => (allKeys.add(key), value));
    return JSON.stringify(obj, Array.from(allKeys).sort(), space);
}

class MySet extends Set {
    // The constructor makes uses of add(), so we don't need
    // to override the constructor.

    has(item) {
        return super.has(JSONstringifyOrder(item));
    }
    
    add(item) {
        return super.add(JSONstringifyOrder(item));
    }
    
    delete(item) {
        return super.delete(JSONstringifyOrder(item));
    }
}


const set = new MySet([[1,2,3], [1,2,3], 1, 2, 1]);
set.add([1,2,3]);
set.add({ a: { s: 1, d: 2 }, f: 3 });
set.add({ f: 3, a: { d: 2, s: 1 } });

// Stack Overflow snippets cannot print Set instances to the console
console.log(Array.from(set));
// or unserialized
Array.from(set, json => JSON.parse(json)).forEach(item => console.log(item));

about 4 years ago · Juan Pablo Isaza Report
Answer question
Find remote jobs

Discover the new way to find a job!

Top jobs
Top job categories
Business
Post vacancy Pricing Sales
Legal
Terms and conditions Privacy policy
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Show me some job opportunities
There's an error!