在ES6中使链表可迭代

时间:2017-02-16 23:26:43

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

我在JavaScript中有一个链接列表,我需要使用$('#add_product_field').on('click', function (){ //Destroy typeahead $('.search').typeahead('destroy'); //..add a new input to DOM code //attach typeahead to all inputs typeahead_initialize(); }); 循环进行迭代。我差不多完成了它,但似乎没有办法让第一个值包含在结果中。这是一个简化版本:

for of

2 个答案:

答案 0 :(得分:6)

问题是您在检索current之前将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);
}




使用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 :(得分: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;
  } 
}