为什么 Map 构造函数不接受可迭代元组数组?
Why doesn't accept the Map constructor an Array of iterable tuples?
我在 Javascript 中创建了一个实现 Iterable
协议的元组类型。现在应该很容易转换为 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
的构造函数被定义为接受 key/value 对象的任何 Iterable,其中 key/value 对象被定义为 属性 0
的对象是键,属性 1
是值。它没有说明允许 key/value 对象的 Iterables。 (如果它确实允许它们并定义它会恰好调用迭代器两次,那可能会很酷,但是......那不是他们所做的。:-)它会更复杂...)
如果我们查看 the spec,如果您的 Tuple
支持属性 0
(对于键)和 1
(对于值),则它可以工作。例如:
// (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"
const Tuple = (...args) => Object.entries({[args.shift()]: args.shift()});
const map = new Map(Tuple(0, "a").concat(Tuple(1, "b")));
console.log(map.get("0"), map.get("1"));
I created a tuple type in Javascript that implements the Iterable
protocol.
不要。元组具有独特的 属性 ,它们具有固定长度,每个元素都有(可以有)自己的类型,而(可迭代的)集合由 相同 类型的多个元素组成.当然 JavaScript 不关心类型(所有数组都是异构的),但作为程序员的你应该关心。
Why does Map
only accept an Iterable
for the outer composite type, not for the inner pairs?
出于完全相同的原因。元素是 对 或二元组,表示为数组(因为缺少另一种数据结构,并且不必像迭代器结果那样引入一个简单性)。它们总是恰好有两个元素,可访问为 [0]
和 [1]
(它们甚至不需要 .length
!),并且绝对没有理由迭代它们。
我在 Javascript 中创建了一个实现 Iterable
协议的元组类型。现在应该很容易转换为 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
的构造函数被定义为接受 key/value 对象的任何 Iterable,其中 key/value 对象被定义为 属性 0
的对象是键,属性 1
是值。它没有说明允许 key/value 对象的 Iterables。 (如果它确实允许它们并定义它会恰好调用迭代器两次,那可能会很酷,但是......那不是他们所做的。:-)它会更复杂...)
如果我们查看 the spec,如果您的 Tuple
支持属性 0
(对于键)和 1
(对于值),则它可以工作。例如:
// (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"
const Tuple = (...args) => Object.entries({[args.shift()]: args.shift()});
const map = new Map(Tuple(0, "a").concat(Tuple(1, "b")));
console.log(map.get("0"), map.get("1"));
I created a tuple type in Javascript that implements the
Iterable
protocol.
不要。元组具有独特的 属性 ,它们具有固定长度,每个元素都有(可以有)自己的类型,而(可迭代的)集合由 相同 类型的多个元素组成.当然 JavaScript 不关心类型(所有数组都是异构的),但作为程序员的你应该关心。
Why does
Map
only accept anIterable
for the outer composite type, not for the inner pairs?
出于完全相同的原因。元素是 对 或二元组,表示为数组(因为缺少另一种数据结构,并且不必像迭代器结果那样引入一个简单性)。它们总是恰好有两个元素,可访问为 [0]
和 [1]
(它们甚至不需要 .length
!),并且绝对没有理由迭代它们。