1

From JavaScript Iterators

var Iterator = function(arr){ return {
    index : -1,
    hasNext : function(){ return this.index <= arr.length; },
    hasPrevious: function(){ return this.index > 0; },

    current: function(){ return arr[ this["index"] ]; },

    next : function(){
        if(this.hasNext()){
            this.index = this.index + 1;            
            return this.current();
        } 
        return false;
    },

    previous : function(){
        if(this.hasPrevious()){
            this.index = this.index - 1
            return this.current();
        }
        return false;
    }
}   
};

var iter = Iterator([1,2,3]);

I want to rewrite this functionality through the addition of dynamic values

   added : function(data){
          arr.push(data);
          this.index++
        }


iter.added(1);
iter.added(6);
iter.added(7);
iter.added(8);

How do it ? I knows about iterator in ES 6 https://developer.mozilla.org/ru/docs/Web/JavaScript/Reference/Global_Objects/Iterator but i want support IE

Community
  • 1
  • 1
zloctb
  • 10,592
  • 8
  • 70
  • 89
  • Remove the `this.index++` from `added` and it will work. Or doesn't it? Why not? – Bergi Feb 24 '16 at 14:28
  • OK..... but i want when added then current index change – zloctb Feb 24 '16 at 14:29
  • 1
    Ok, that's unexpected to me but go for it. Now what is your question? – Bergi Feb 24 '16 at 14:30
  • Are you trying to implement [`next(value)`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Generator/next) similar to `.send` in python? – georg Feb 24 '16 at 14:33
  • 1
    Btw, that `hasNext` method gives wrong results – Bergi Feb 24 '16 at 14:47
  • Why should the index change after you add an item? Added items are put at the end of the array, so increasing the index causes you to skip items. And as Bergi already mentioned, `hasNext` doesn't work correctly - `arr.length - 1` is the last valid index, so there's only a next item when `index < arr.length - 1`. Also, `next` and `previous` return the current item on success - but an array can also contain falsy values, so you cannot distinguish between success and failure in that case. The code you have copied certainly has not been tested properly, as its author already said. ;) – Pieter Witvoet Feb 24 '16 at 15:12

1 Answers1

1

You'd need to add the added() function similar to what you posted, then update the initial value of index so the next() and previous() functions work. You'd need to set it to the input array length so the next() function knows you're at the last element.

var Iterator = function(arr){ return {
    index : arr.length,
    hasNext : function(){ return this.index < arr.length - 1; },
    hasPrevious: function(){ return this.index > 0; },

    current: function(){ return arr[ this.index ]; },

    next : function(){
        if(this.hasNext()){
            this.index = this.index + 1;            
            return this.current();
        } 
        return false;
    },

    previous : function(){
        if(this.hasPrevious()){
            this.index = this.index - 1
            return this.current();
        }
        return false;
    },

    added: function(x){
        arr.push(x);
      this.index++;
    }
}   
};

var iter = Iterator([1,2,3]);
console.log(iter)
iter.added(1);
iter.added(6);
iter.added(7);
iter.added(8);
console.log(iter)
console.log(iter.next())
console.log(iter.previous())
console.log(iter.previous())
console.log(iter.previous())
console.log(iter.previous())
console.log(iter.next())
console.log(iter.current())

Which outputs:

Object {arr: Array[3], index: 3}
Object {arr: Array[7], index: 7}
false
8
7
6
1
6
6

Here it is in a fiddle: https://jsfiddle.net/8ojcrnkn/5/

Hope that helps!

Adam Konieska
  • 2,805
  • 3
  • 14
  • 27
  • What exactly did you change in the code? What do you mean by "declare `arr`", it already is declared? – Bergi Feb 24 '16 at 14:31
  • You need to be able to access `arr` from the `added` function, so you'd need to add it, see line 2. – Adam Konieska Feb 24 '16 at 14:32
  • When I call iter.next() return 6 .... but I want then return false /// only support prev() – zloctb Feb 24 '16 at 14:36
  • No, you don't. It's already accessible through closure, as it's a parameter of the `Iterator` function. Notice that you're not even accessing the `.arr` property anywhere in the posted code. – Bergi Feb 24 '16 at 14:37
  • @bergi notice that its in the `added` function. And without declaring it as a property its inaccessible by that function. – Adam Konieska Feb 24 '16 at 14:39
  • 1
    @AdamKonieska: Notice that it's also in the `hasNext` and `current` functions. And nowhere it is accessed as a property. You don't need that. You can directly access the variable. See [How do JavaScript closures work?](http://stackoverflow.com/q/111102/1048572) – Bergi Feb 24 '16 at 14:44
  • 1
    @zloctb: If you want the iterator to start at the end, you should make that `index: arr.length` – Bergi Feb 24 '16 at 14:46
  • @zloctb actually you'd need arr.length+1 to be at the end of the array, so your `next()` function returns false. I've updated the answer and fiddle with an example. Hope that helps :-) – Adam Konieska Feb 24 '16 at 14:48
  • @AdamKonieska: Now with the cleanup you've destroyed the `current` method which should return the current element, not the current index. And `hasNext` should actually check for `this.index+1 < arr.length`, but that's wrong in the original code even. – Bergi Feb 24 '16 at 15:01
  • I still insist on `this.index + 1` in `hasNext`, but the rest looks good now. – Bergi Feb 24 '16 at 15:20
  • @Bergi with `this.index + 1` it goes out of bounds. I think we want `this.index < arr.length-1` to check if we can move 1 position. – Adam Konieska Feb 24 '16 at 15:24
  • @AdamKonieska: `this.index+1 < arr.length` is equivalent to `this.index < arr.length-1`, yes, that's what we need. – Bergi Feb 24 '16 at 15:27
  • @zloctb the example was updated. I added the link to a fresh JS fiddle. Hope that helps. – Adam Konieska Feb 24 '16 at 15:44