Please find the complete code example in action here.
我尝试将生成器用作迭代器,并将其与for..of
中的toString
循环结合使用,但不知怎的,它无效。
这是我的(生成器)迭代器的样子 -
*[Symbol.iterator]() {
let temp = this.head;
while (temp) {
yield temp.item;
temp = temp.next;
}
}
然后我尝试在toString
方法中使用它,如下所示 -
[Symbol.toStringTag]() {
for (const temp of this) {
return `${temp} -> `;
}
}
我认为使用带有for..of
引用的this
循环应该调用迭代器,但它不会。这可以通过控制台日志中缺少Iterator called
语句来观察,而使用默认toString
打印对象。
我有什么遗失的吗?
答案 0 :(得分:0)
你有几个大问题
Symbol.toStringTag
应该是解析为字符串的属性,而不是函数。这意味着
[Symbol.toStringTag]() {
应该是
get [Symbol.toStringTag]() {
这样该属性就是一个getter,它将在访问时返回一个字符串。
console.log(list)
未致电.toString()
,因此您需要console.log(list.toString())
。
您会注意到,list.toString() === "[object 1 -> ]"
,也可能不是您想要的。 toStringTag
被附加在另一个字符串中,有点像
`[object ${this[Symbol.toStringTag]}]`
所以如果你真的想要一个很好的字符串输出,你可能只想要
toString() {
作为您的方法,跳过toStringTag
。
如果您尝试序列化整个列表,那么您的循环没有意义,因为您return
列表中的第一项,并且从不费心处理剩余的项目。
所以最后,我可能会写出你想要做的事情
toString() {
let result = "";
for (let item = this.head; item; item = item.next) {
if (result) result += ' -> ';
result += item.item;
}
return result;
}
答案 1 :(得分:0)
我认为在这个引用中使用
for..of
循环应该调用迭代器,但它不会。
确实如此。你刚才从未在你的例子中调用过该方法。
使用默认
将对象打印到控制台toString
代替
它没有,它是使用控制台自己的对象表示打印的(在babeljs.io repl上,它似乎是.constructor.name
和JSON.stringify
的混合。)
...
toString
方法如下所示 -[Symbol.toStringTag]() { …
没有。 toString
由Object.prototype
继承时,Symbol.toStringTag
用作标准toString
表示的一部分。它不是一种方法,而是一种普通的价值(你可以使用一个吸气剂,但你不应该)。
如果要实现自定义class SLListNode {
constructor(item, next) {
this.item = item;
this.next = next;
}
toString() {
return `${this.item} -> ${this.next}`;
}
}
class SinglyLinkedList {
constructor() {
this.length = 0;
this.head = null;
}
addFirst(item) {
this.head = new SLListNode(item, this.head);
this.length++;
}
*[Symbol.iterator]() {
console.log('Iterator called');
let temp = this.head;
while (temp) {
yield temp.item;
temp = temp.next;
}
}
getLength() {
return this.length;
}
toString() {
return `{ ${this.head.toString()} }`;
}
}
SinglyLinkedList.prototype[Symbol.toStringTag] = "LinkedList";
const list = new SinglyLinkedList();
list.addFirst(3);
list.addFirst(2);
list.addFirst(1);
console.log(String(list)); // "{ 1 -> 2 -> 3 -> null }"
console.log(Object.prototype.toString.call(list)); // "[object LinkedList]"
方法,请实际执行 。
这是一个更新的示例,可以满足您的需求:
SELECT sum(spend) AS spend
FROM sales_fact
WHERE person_id IN
(
SELECT person_id
FROM enrollment_fact
WHERE program = 'blah'
GROUP BY person_id
)
答案 2 :(得分:0)
感谢@bergi和@loganfsmyth,他的答案指出了原始代码中的错误,并将我推向了正确的方向,这里的解决方案有效并利用生成器作为迭代器 -
class SLListNode {
constructor(item) {
this.item = item;
}
toString() {
return `${this.item}`;
}
}
class SinglyLinkedList {
constructor() {
this.length = 0;
}
addFirst(item) {
const newNode = new SLListNode(item);
newNode.next = this.head;
this.head = newNode;
this.length++;
}
*[Symbol.iterator]() {
let temp = this.head;
while (temp) {
yield temp.item;
temp = temp.next;
}
}
getLength() {
return this.length;
}
toString() {
let str = "";
for (const temp of this) {
str = `${str} -> ${temp}`;
}
return str;
}
}
const list = new SinglyLinkedList();
list.addFirst(3);
list.addFirst(2);
list.addFirst(1);
console.log(list.toString());