我在 Javascript 中创建了一个实现 Iterable
协议(protocol)的元组类型。现在应该很容易转换为 Map
:
const Tuple = (...args) => {
const Tuple = f => f(...args);
Tuple[Symbol.iterator] = () => args[Symbol.iterator]();
return Tuple;
};
new Map([Tuple(1, "a"), Tuple(2, "b")]); // Map {undefined => undefined}
相反,我必须手动进行转换:
const Tuple = (...args) => {
const Tuple = f => f(...args);
Tuple[Symbol.iterator] = () => args[Symbol.iterator]();
return Tuple;
};
const toArray = tx => tx((...args) => args);
const Map_ = (...pairs) => {
return new Map(pairs.map(pair => toArray(pair)));
};
const map = Map_(Tuple(1, "a"), Tuple(2, "b"));
console.log(map.get(1), map.get(2)); // "a" "b"
似乎 Map
只接受外部复合类型的 Iterable
,而不是内部对。我错过了什么?还有其他方法可以实现转换吗?
最佳答案
Map
的构造函数被定义为接受任何可迭代的键/值对象,其中键/值对象被定义为属性 0
是键的对象,属性 1
是值。它没有提到允许 Iterables 用于键/值对象。 (如果它确实允许它们并定义它会恰好调用迭代器两次,那可能会很酷,但是......那不是他们所做的。:-)而且它会更多复杂...)
如果我们看the spec ,如果它支持属性 0
(对于键)和 1
(对于值),您的 Tuple
就会工作。例如:
// (Defined this way because you seemed to want a non-constructor)
const TupleMethods = {
get "0"() {
return this.key;
},
get "1"() {
return this.value;
}
};
const Tuple = (key, value) => {
const t = Object.create(TupleMethods);
t.key = key;
t.value = value;
return t;
}
// Usage:
const m = new Map([
Tuple("one", "uno"),
Tuple("two", "due"),
Tuple("three", "tre")
]);
console.log(m.get("two")); // "due"
您在评论中提到了不变性。也许:
// (Defined this way because you seemed to want a non-constructor)
const TupleMethods = {};
Object.defineProperties(TupleMethods, {
"0": {
get() {
return this.key;
}
},
"1": {
get() {
return this.value;
}
}
});
const Tuple = (key, value) => {
const t = Object.create(TupleMethods);
Object.defineProperties(t, {
key: {
value: key
},
value: {
value: value
}
});
return t;
};
// Usage:
const m = new Map([
Tuple("one", "uno"),
Tuple("two", "due"),
Tuple("three", "tre")
]);
console.log(m.get("two")); // "due"
关于javascript - 为什么 Map 构造函数不接受可迭代元组数组?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44099196/