Показать сообщение отдельно
  #2 (permalink)  
Старый 23.09.2011, 23:26
sinistral
Посмотреть профиль Найти все сообщения от melky
 
Регистрация: 28.03.2011
Сообщений: 5,418

Iterator pattern. ну надо же, наконец то я его попробую.


function Itr(source, onnext, startInd) {
    // что будет просчитывать
    this.source = source;
    // при изменении указателя будет вызываться эта функция
    this.onnext = typeof onnext == "function" ? onnext : function() {};
    // указатель
    this.index = typeof startInd == "number" ? startInd : 0;
};

Itr.prototype = {
    
    // изменить указатель на "delta" единиц и породить псевдособытие "next"
    
    // delta :
    // >0 - вправо, <0 - влево. (сдвиг указателя)
    change: function(delta) {
        
        var ob = this;


        if (ob.index + delta in ob.source) {


            ob.onnext(ob.source[ob.index += delta]);

            return ob.current();

        } else return undefined;


    },
    
    //обёртки для change
    next: function() {
        return this.change(1);
    },
    previous: function() {
        return this.change(-1)
    },
    
    
    // получить текущий элемент итератора
    current: function() {
        return this.source[this.index]
    }
};





вроде организовано всё сложно, но оно всё просто, на самом деле

Itr итерирует не только массивы, но и пронумерованные объекты вообще.

что это такое ?

к примеру, это
obj = {
    "0" : "первый член",
    "1" : "второй член"
}

свойство, показывающее длину, не нужно! Spoiler : (проверка существования сделана отлично от цикла по массиву - я про длину).

чтобы создать итератор, можно написать так.

var myIterator = new Itr( myIterateObject/*что будет итерировать*/ );

т.е. использовать другие аргументы необязательно - обработчик псевдособытия сдвига указателя будет пустой функцией, а указатель - нулём.

функция current сдвигает указатель на N единиц и порождает пседособытие next.
index = index + delta


методы next и current сдвигают указатель на 1 и -1 соответственно. (т.е. вызывают функцию change такими аргументами)

чтобы получить текущий элемент итератора, можно вызвать метод current.

ну и наконец, тестовые примеры

пример с использованием всех аргументов.
function Itr(a,b,c){this.source=a;this.onnext=typeof b=="function"?b:function(){};this.index=typeof c=="number"?c:0}Itr.prototype={change:function(a){if(this.index+a in this.source)return this.onnext(this.source[this.index+=a]),this.current()},next:function(){return this.change(1)},previous:function(){return this.change(-1)},current:function(){return this.source[this.index]}};
/* -------  SCRIPT  END    ---------*/


// что будем считать
var arr = ["слово;число", "слово1;число1", "слово2;число2"];

// откуда будем считать

// т.к. начальный указатель - нуль, а "next" немедленно передвинет указатель вправо,
// то ставим -1, чтобы при "next" он стал нулём.  
var startIndex = -1;

// ваши переменные a и b
var a,b;

// обработчик псевдособытия. вызывается при изменении указателя.
// передается текущий элемент
var handler = function(current) {
    
    var c = current.split(";");
    
    a = c[0]; // "слово"
    b = c[1]; // "число"
    
    alert( "a = "+a+", b = "+b );
}

    
var ex = new Itr(arr,handler,startIndex);
// этого хватит для итерации, если всё указано :)
while( ex.next() ) ;


и пример с использованием без дополнительных аргументов.
function Itr(a,b,c){this.source=a;this.onnext=typeof b=="function"?b:function(){};this.index=typeof c=="number"?c:0}Itr.prototype={change:function(a){if(this.index+a in this.source)return this.onnext(this.source[this.index+=a]),this.current()},next:function(){return this.change(1)},previous:function(){return this.change(-1)},current:function(){return this.source[this.index]}};
/* -------  SCRIPT  END    ---------*/


// что будем считать
var arr = ["слово;число", "слово1;число1", "слово2;число2"];


// ваши переменные a и b
var a,b;


    
var ex = new Itr(arr);

// опять таки ставим индекс в минус один
ex.index = -1;


while( ex.next() ) {

    var c = ex.current().split(";");
    
    a = c[0]; // "слово"
    b = c[1]; // "число"
    
    alert( "a = "+a+", b = "+b );

}

Последний раз редактировалось melky, 23.09.2011 в 23:50.
Ответить с цитированием