我在我的库big-m 中创建了一个名为 CanonMap 的类,以通过散列而不是引用来封装映射。
默认情况下,它适用于元组、日期和简单对象:
const { CanonMap } = "big-m";
const myMap = new CanonMap();
myMap.set(
["Farooq", "867-5309"],
36.59
);
myMap.get(
["Farooq", "867-5309"]
) === 36.59;
myMap.set(
{name: "Farooq", number: "867-5309"},
36.59
);
myMap.get(
{number: "867-5309", name: "Farooq"} // Insensitive to key ordering
) === 36.59;
myMap.set(new Date(2012, 6, 5), "Tuesday");
myMap.get(new Date(2012, 6, 5)) === "Tuesday";
它还可以使用自定义的“canonizer”函数进行扩展,该函数确定如何散列值:
import {naiveCanonize, jsonCanonize, JsonCanonMap, CanonMap} from "big-m";
// Same as default canonizer, but with greater recursion depth (default is 2)
new CanonMap([], 6);
// Canonize by ID with fallback to naive
const customCanonMap = new CanonMap([
[{id: "TEST1", x: 7}, 77],
[{ x: 7 }, 88]
], lookup => lookup.id || naiveCanonize(lookup));
customCanonMap.get({id: "TEST1", x: 8}) === 77; // Ignores other values, uses ID
customCanonMap.get({x: 8}) === undefined; // Uses all fields, so lookup fails
// Default canonizer with JSON.stringify
new CanonMap([], jsonCanonize);
// equivalent to
new CanonMap([], lookup => JSON.stringify(lookup));
// also equivalent to
new JsonCanonMap();
最后,如您所描述的,要实现使用对象本身的原型哈希函数的 CanonMap,您可以执行以下操作:
const selfHashingCanonMap = new CanonMap([], lookup => {
if ("hash" in lookup) {
return lookup.hash();
} else {
return naiveCanonize(lookup);
}
});