ES5如何在数据类上实现.Net IEqualityComaparer以进行比较?

当我想使用自定义类型T作为.Net中的哈希键时,我实现了IEqualityComparer并将其传递给哈希图,例如DictionaryHashSet添加新项目后,将调用GetHashCodeEquals方法来检查两个T实例是否相同。

例如,我有一个不变的数据类Foo

sealed class Foo
{
    public Foo(int field1,string field2)
    {
        Prop_1 = field1;
        Prop_2 = field2;
    }

    public int Prop_1 { get; }
    public string Prop_2 { get; }
}

FooEuqalityComparer

sealed class FooEuqalityComparer : IEqualityComparer<Foo>
{
    public bool Equals(Foo x,Foo y)
    {
        return x == null ? y == null :
            x.Prop_1 == y.Prop_1 &&
            x.Prop_2 == y.Prop_2;
    }

    public int GetHashCode(Foo obj)
    {
        if (obj == null)
            return 0;

        return obj.Prop_1.GetHashCode() ^ obj.Prop_2.GetHashCode();
    }
}

测试:

var set = new HashSet<Foo>(new FooEuqalityComparer());

var foo1 = new Foo(1,"foo 1");
var not_foo2 = new Foo(1,"foo 1");
var foo3 = new Foo(3,"foo 3");

set.Add(foo1);
set.Add(not_foo2);
Assert.AreEqual(1,set.Count);
Assert.AreSame(foo1,set.Single());

set.Add(foo3);
Assert.AreEqual(2,set.Count);

如何在Node.js中做到这一点?

无法覆盖toString(),因为我想保留对该对象的引用作为map中的键。


经过一番搜索,我意识到javascript或ECMAScript使用SameValueZero算法来比较对象,最好的方法仍然是使用字符串作为键。 所以我用两个地图来实现这一点:

class ObjectKeyMap {
  /**
   * @param {Object[]} keys -
   * @param {function():string} keys[].getHashCode -
   * @param {function(Object):T} valueSelector -
   *
   * @typedef {Object} T
   */
  constructor(keys,valueSelector) {
    const keyReferences = {};
    keys.forEach(it => {
      keyReferences[it.getHashCode()] = it;
    });
    this.keyReferences = keyReferences;

    this.map = new Map(keys.map(it => [it.getHashCode(),valueSelector(it)]));
  }

  /**
   * @param {string|{getHashCode:function():string}} key -
   *
   * @returns {string}
   */
  _getStringKey(key) {
    if (!key) {
      return null;
    }

    if (Object.prototype.toString.call(key) === "[object String]") {
      return key;
    } else {
      return key.getHashCode();
    }
  }

  /**
   * @param {string|{getHashCode:function():string}} key -
   *
   * @returns {T}
   */
  get(key) {
    const stringKey = this._getStringKey(key);
    if (!stringKey || stringKey === "") {
      return null;
    }

    return this.map.get(stringKey);
  }

  values() {
    return [...this.map.values()];
  }

  /**
   * @param {string|{getHashCode:function():string}} key -
   */
  key(key) {
    const stringKey = this._getStringKey(key);
    if (!stringKey || stringKey === "") {
      return null;
    }
    return this.keyReferences[stringKey];
  }

  keys() {
    return Object.values(this.keyReferences).slice();
  }
}

ObjectKeyMap假定要用作键的对象必须具有getHashCode函数,该函数返回身份字符串。如果使用TypeScript编写,应该更具可读性。

qazzaqqaz4444 回答:ES5如何在数据类上实现.Net IEqualityComaparer以进行比较?

暂时没有好的解决方案,如果你有好的解决方案,请发邮件至:iooj@foxmail.com
本文链接:https://www.f2er.com/3147742.html

大家都在问