2017-02-16 18 views
5

Tôi có một danh sách được liên kết trong JavaScript mà tôi cần để lặp lại với vòng lặp for of. Tôi đã gần như hoàn thành nó nhưng dường như không có cách nào để có được giá trị đầu tiên được đưa vào kết quả. Đây là một phiên bản đơn giản:Tạo danh sách liên kết có thể lặp lại trong ES6

var obj = {value: 1, next: {value: 2, next: {value: 3, next: {value: 4, next: {value: 5, next: {value: 6, next: {value:7, next: null}}}}}}}; 

obj[Symbol.iterator] = function() { 
    var current = this; 
    return { 
    next() { 
     if (current.next !== null) { 
     current = current.next; 
     return {value: current.value, done: false}; 
     } 
     return {done: true} 
    } 
    } 
} 

for (const x of obj) { 
    console.log(x) 
} 

// this is how you get the values printed with no loop 
// console.log(obj.value + '->' + obj.next.value + '->' + obj.next.next.value) 

Trả lời

4

Vấn đề là bạn đang di chuyển current đến nút tiếp theo trước khi lấy các value.

var obj = {value: 1, next: {value: 2, next: {value: 3, next: {value: 4, next: {value: 5, next: {value: 6, next: {value:7, next: null}}}}}}}; 
 

 
obj[Symbol.iterator] = function() { 
 
    var current = this; 
 
    return { 
 
    next() { 
 
     if (current) { 
 
     var value = current.value; 
 
     current = current.next; 
 
     return {value: value, done: false}; 
 
     } 
 
     return {done: true}; 
 
    } 
 
    }; 
 
}; 
 

 
for (const x of obj) { 
 
    console.log(x); 
 
}

Đó là dễ dàng hơn nhiều để thực hiện một iterator với một generator function.

var obj = {value: 1, next: {value: 2, next: {value: 3, next: {value: 4, next: {value: 5, next: {value: 6, next: {value:7, next: null}}}}}}}; 
 

 
obj[Symbol.iterator] = function*() { 
 
    var current = this; 
 
    while (current) { 
 
    yield current.value; 
 
    current = current.next; 
 
    } 
 
}; 
 

 
for (const x of obj) { 
 
    console.log(x); 
 
}

1

Bạn nên thử nghiệm cho current, không current.next:

obj[Symbol.iterator] = function() { 
    var current = this; 
    return { 
    next() { 
     if (current !== null) { 
     var res = {value: current.value, done: false}; 
     current = current.next; 
     return res; 
     } else { 
     return {done: true}; 
     } 
    } 
    }; 
} 

Nhưng có thể viết nó đơn giản như một phương pháp phát nhiều:

obj[Symbol.iterator] = function*() { 
    for (var current = this; current !== null; current = current.next) { 
    yield current.value; 
    } 
} 

Btw, Tôi ould khuyên bạn không nên đặt vòng lặp này trên mỗi nút của danh sách (hoặc thậm chí trên nút đầu tiên). Đặt ở trên một đối tượng riêng biệt mà chỉ vào người đứng đầu danh sách, hoặc làm cho nó một hàm helper tĩnh:

let list = { 
    head: obj, // could be null either 
    *[Symbol.iterator]() { 
    for (var current = this.head; current !== null; current = current.next) { 
     yield current.value; 
    } 
    } 
} 

function* linkedList(head) 
    for (; head !== null; head = head.next) { 
    yield head.value; 
    } 
} 
Các vấn đề liên quan