【问题标题】:Making a linked list iterable in ES6在 ES6 中使链表可迭代
【发布时间】:2017-07-06 07:32:39
【问题描述】:

我在 JavaScript 中有一个链表,我需要使用 for of 循环使其可迭代。我几乎已经完成了,但似乎无法获得结果中包含的第一个值。这是一个简化的版本:

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)

【问题讨论】:

    标签: javascript linked-list iterator ecmascript-6 iterable


    【解决方案1】:

    你应该测试current,而不是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};
          }
        }
      };
    }
    

    但是可以把它写成生成器方法简单得多:

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

    顺便说一句,我建议不要将此迭代器放在列表的每个节点上(甚至放在第一个节点上)。放入指向列表头部的单独对象,或使其成为静态辅助函数:

    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;
      } 
    }
    

    【讨论】:

      【解决方案2】:

      问题是您在检索value 之前将current 移动到下一个节点。

      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);
      }

      使用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);
      }

      【讨论】:

        猜你喜欢
        • 2015-12-30
        • 2016-01-22
        • 2015-06-01
        • 2021-10-21
        • 2020-04-14
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多