leebyron / iterall

🌻 Minimal zero-dependency utilities for using Iterables in all JavaScript environments.

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Iterator & Iterable Protocol

kennetpostigo opened this issue · comments

Hi, I've been trying implement a few mutable data structures to gain a better understanding of data structures. I want to document and create examples on a documentation site from my learning so that others interested in the topic can learn from my experiences. So as I was working on this I started by implementing Stack, Queue, and LinkedList. As I was finishing up LinkedList and going to continue to SetI started to think about how I've been going about iterating through my Data Structures and the Generator Iterator came into my mind. So I did some googling and found the MDN Iteration Protocols and the iterall github repo.

I read through the MDN page and I started reading your README for this package. After reading both I'm a bit confused about the difference between @@iterator, $$iteratorand [Symbol.iterator].

I want to start by implementing Iterator on my(noob) LinkedList implementation but I'm not sure exactly the way to go about it. I started out using a get() method that would iterate and return a value based on the index you supplied. Then realized I should use get() within insert and delete. When I wanted to implement indexOf() but it iterates based on a value. Then It hit me that I'm missing something very important that would help prevent implementing iteration multiple times, the Iterator! If I implemented it I would be able to forgo iterating in indexOf() manually and just use Iterator and would be able to do the same for all the other methods that need to iterate. So heres my code and not sure what to name the iterator method because I'm not sure about the differences between @@iterator, $$iteratorand [Symbol.iterator]:

// I'm using flow types
class Node {
  data: ?any
  next: ?Node;
  prev: ?Node;

  constructor (data: any) {
    this.data = data;
    this.next = null;
    this.prev = null;
  }
}

export class LinkedList {
  head: ?Node;
  tail: ?Node;
  length: number;
  push: Function;
  ...

  constructor () {
    this.length = 0;
    this.head = null;
    this.tail = null;
  }

  push (element: Node): void {
    ...
  }

  unshift (element: Node): void {
    ...
  }

  pop (): ?Node {
    ...
  }

  shift (): ?Node {
    ...
  }

  insert (index: number, element: Node): void {
    var current: ?Node = this.get(index);
    if (current) {
      var newNode: Node = new Node(element),
          previous: ?Node = current.prev;
      if (previous) {
        previous.next = newNode;
        newNode.prev = previous;
        newNode.next = current;
        current.prev = newNode;
      }
    }
  }

  get(index: number): ?Node {
    if (index > 0 && index <= this.length + 1) {
      if (this.head) {
        var current: Node = this.head,
            previous: ?Node,
            pointer: number = 0;
        while(pointer++ <= index) {
          if (pointer < index) {
            previous = current;
            if (current.next) current = current.next;
          }
        }
        return current;
      }
    }
    return null;
  }

  delete (index: number): ?Node {
    var current: ?Node = this.get(index);
    if (current) {
      var previous = current.prev,
          next = current.next;
      if (previous && next) {
        previous.next = next;
        next.prev = previous;
        this.length++;
      }
    }
    return null;
  }
  // bare/not functioning implementation
  [Symbol.iterator] () {
    var Ll = this
    return {
      index: 0,
      next () {
        if (this.index >= Ll.length) {
          return { value: undefined, done: true };
        }
        return { value: [someValue form Ll], done: false };
      }
    }
  }

  isEmpty (): boolean {
    return this.length === 0;
  }
}

Check out the API section at the bottom of the Readme that explains the differences. https://github.com/leebyron/iterall/blob/master/README.md#api

To sum up, Symbol.iterator is the official value of the Iterable protocol for ES6 environments, but not all JS environments support ES6, like most older browsers. "@@iterator" is a string that Firefox used to use before ES6. $$iterator is a variable that's set to Symbol.iterator || "@@iterator"