- Source:
The Hashable interface must be implemented by any object that can be hashed.
const assert = require('assert');
const {
Hashable, bytes2hex, hashDirectly, hashUnorderedWith, iter,
hashWith, hex2bytes, randomBuildHasher, curry, builder,
} = require('ferrum');
class UnorderedPair {
constructor(fst, scd) {
Object.assign(this, { fst, scd });
}
[Hashable.sym](hasher) {
// It is a best practice to start any container with a uuid
// and the container size, so differently sized containers
// and containers of different types produce different hashes.
// We could supply uuid & the size without bytes2hex or hashDirectly,
// but using those has two advantages: (1) They are faster and
// (2) using them bypasses any special behaviour in the Hasher
// defined for numbers or strings.
// We only want that special behaviour to be used on actual content
// not the header of our type
hasher.update(hex2bytes('d5bb31067ea846c197dcac3cae48f327'));
hasher.update(hashDirectly(2));
// Since we're a UnorderedPair we want the order of the elements
// to not matter so we should use hashUnorderedWith. We use the
// hasher's buildHasher in case that implements any special behaviour.
// If we did not need order independence, we would just iterate over the
// elements: `each(this, (v) => hasher.update(v))`
hasher.update(hashUnorderedWith(this, hasher.buildHasher));
}
[Symbol.iterator]() {
return iter([this.fst, this.scd]);
}
};
UnorderedPair.new = curry('UnorderedPair.new', builder(UnorderedPair));
const h = hashWith(randomBuildHasher());
assert.strictEqual(
bytes2hex(h(UnorderedPair.new({}, 42))),
bytes2hex(h(UnorderedPair.new({}, 42))));
By default implemented for: String, Number, Boolean, RegExp, Date, Symbol, Function, null, undefined, typed arrays, URL, Set, Map, Object
Version history
- 1.9.0 Initial implementation