hashing~ Hashable


The Hash­able in­ter­face must be im­ple­men­ted by any ob­ject that can be hashed.

const as­sert = re­quire('assert');
const {
  Hash­able, bytes2hex, hash­Dir­ectly, hashUn­ordered­With, iter,
  hash­With, hex2­bytes, ran­dom­Build­Hasher, curry, builder,
} = re­quire('fer­rum');

class Un­ordered­Pair {
  con­structor(fst, scd) {
    Ob­ject.as­sign(this, { fst, scd });

  [Hash­able.sym](hasher) {
    // It is a best prac­tice to start any con­tainer with a uuid
    // and the con­tainer size, so dif­fer­ently sized con­tain­ers
    // and con­tain­ers of dif­fer­ent types pro­duce dif­fer­ent hashes.
    // We could sup­ply uuid & the size without bytes2hex or hash­Dir­ectly,
    // but us­ing those has two ad­vant­ages: (1) They are faster and
    // (2) us­ing them by­passes any spe­cial be­ha­viour in the Hasher
    // defined for num­bers or strings.
    // We only want that spe­cial be­ha­viour to be  used on ac­tual con­tent
    // not the header of our type

    // Since we're a Un­ordered­Pair we want the or­der of the ele­ments
    // to not mat­ter so we should use hashUn­ordered­With. We use the
    // hash­er's build­Hasher in case that im­ple­ments any spe­cial be­ha­viour.
    // If we did not need or­der in­de­pend­ence, we would just it­er­ate over the
    // ele­ments: `each(this, (v) => hasher.up­date(v))`
    hasher.up­date(hashUn­ordered­With(this, hasher.build­Hasher));

  [Sym­bol.iter­ator]() {
    re­turn iter([this.fst, this.scd]);

Un­ordered­Pair.new = curry('Un­ordered­Pair.new', builder(Un­ordered­Pair));

const h = hash­With(ran­dom­Build­Hasher());
  bytes2hex(h(Un­ordered­Pair.new({}, 42))),
  bytes2hex(h(Un­ordered­Pair.new({}, 42))));

By de­fault im­ple­men­ted for: String, Num­ber, Boolean, Reg­Exp, Date, Sym­bol, Func­tion, null, un­defined, typed ar­rays, URL, Set, Map, Ob­ject

Ver­sion his­tory

  • 1.9.0 Ini­tial im­ple­ment­a­tion