How to customize object equality for JavaScript Set

后端 未结 9 1371
臣服心动
臣服心动 2020-11-22 16:48

New ES 6 (Harmony) introduces new Set object. Identity algorithm used by Set is similar to === operator and so not much suitable for comparing objects:

9条回答
  •  庸人自扰
    2020-11-22 16:51

    Comparing them directly seems not possible, but JSON.stringify works if the keys just were sorted. As I pointed out in a comment

    JSON.stringify({a:1, b:2}) !== JSON.stringify({b:2, a:1});

    But we can work around that with a custom stringify method. First we write the method

    Custom Stringify

    Object.prototype.stringifySorted = function(){
        let oldObj = this;
        let obj = (oldObj.length || oldObj.length === 0) ? [] : {};
        for (let key of Object.keys(this).sort((a, b) => a.localeCompare(b))) {
            let type = typeof (oldObj[key])
            if (type === 'object') {
                obj[key] = oldObj[key].stringifySorted();
            } else {
                obj[key] = oldObj[key];
            }
        }
        return JSON.stringify(obj);
    }
    

    The Set

    Now we use a Set. But we use a Set of Strings instead of objects

    let set = new Set()
    set.add({a:1, b:2}.stringifySorted());
    
    set.has({b:2, a:1}.stringifySorted());
    // returns true
    

    Get all the values

    After we created the set and added the values, we can get all values by

    let iterator = set.values();
    let done = false;
    while (!done) {
      let val = iterator.next();
    
      if (!done) {
        console.log(val.value);
      }
      done = val.done;
    }
    

    Here's a link with all in one file http://tpcg.io/FnJg2i

提交回复
热议问题