function dict(factory, origin) {
return new Proxy({ ...origin }, {
get(dict, key) {
// Ensure that "missed" keys are set into
// The dictionary with default values
if (!dict.hasOwnProperty(key)) {
dict[key] = factory()
}
return dict[key]
}
})
}
下面的代码:
n = dict(Number, [[0, 1], [1, 2], [2, 4]])
// Zero is the default value mapped into 3
assert(n[3] == 0)
// The key must be present after calling factory
assert(Object.keys(n).length == 4)
class DefaultDict {
constructor(defaultInit) {
this.original = defaultInit;
return new Proxy({}, {
get: function (target, name) {
if (name in target) {
return target[name];
} else {
if (typeof defaultInit === "function") {
target[name] = new defaultInit().valueOf();
} else if (typeof defaultInit === "object") {
if (typeof defaultInit.original !== "undefined") {
target[name] = new DefaultDict(defaultInit.original);
} else {
target[name] = JSON.parse(JSON.stringify(defaultInit));
}
} else {
target[name] = defaultInit;
}
return target[name];
}
}
});
}
}
var a = new DefaultDict(Array);
a["banana"].push("ya");
var b = new DefaultDict(new DefaultDict(Array));
b["orange"]["apple"].push("yo");
var c = new DefaultDict(Number);
c["banana"] = 1;
var d = new DefaultDict([2]);
d["banana"].push(1);
var e = new DefaultDict(new DefaultDict(2));
e["orange"]["apple"] = 3;
var f = new DefaultDict(1);
f["banana"] = 2;
8条答案
按热度按时间qvsjd97n1#
您可以使用JavaScript
Proxy
构建一个这使您可以在访问属性时使用与普通对象相同的语法。
为了使其更清晰一些,可以将其 Package 在构造函数中,或者使用类语法。
**EDIT:**以上实现仅适用于原语。它也应该通过接受默认值的构造函数来处理对象。下面是一个实现,它应该可以使用原语和构造函数。
r6l8ljro2#
查看pycollections.js:
bihw5rsg3#
我不认为有对等的,但你总是可以写自己的。JavaScript中字典的等价物是一个对象,因此可以这样编写它
那就这样叫吧
bvpmtnay4#
可以使用
Proxy
构造一个快速的脏黑客下面的代码:
iqxoj9l95#
Proxies绝对使语法最像Python,有一个名为defaultdict2的库,它提供了一个非常清晰和彻底的基于代理的实现,支持nested/recursive defaultdicts,这是我真正重视的,也是我在这个线程中迄今为止的其他答案中所缺少的。
也就是说,我倾向于使用基于函数的方法来保持JS更“香草”/“原生”,比如这个概念验证:
DefaultMap
的构造函数接受一个返回叶节点默认值的函数。结构的基本操作是put
和get
,后者是不言自明的。put
生成一个嵌套键链,并返回一对函数,让您在这些键的末尾改变或设置叶节点。访问.root
可以得到底层的Map
结构。如果我忽略了任何错误或错过了有用的功能,请随时留下评论,我会把它扔进去。
mrphzbgm6#
受@Andy Carlson的答案启发,这里有一个以稍微更Python的方式工作的实现:
基本上,它还允许您检索“目标”的所有gotten和set值,类似于
collections.defaultdict
在Python中的工作方式。这使我们能够执行以下操作:v7pvogib7#
为了补充安迪·卡尔森的回答
如果你默认dict一个数组,你会在结果对象中得到一个toJSON字段。你可以通过解构一个新的对象来摆脱它。
pftdvrlh8#
原来的答案似乎不适用于嵌套的情况。我做了一些修改,使其工作:
不同的是,如果defaultInit是一个对象,我们需要返回对象的深层副本,而不是原始副本。