Skip to content

Instantly share code, notes, and snippets.

@DmitriiNazimov
Last active April 25, 2024 15:23
Show Gist options
  • Save DmitriiNazimov/2e8898df5796d81c41afdc291d468c29 to your computer and use it in GitHub Desktop.
Save DmitriiNazimov/2e8898df5796d81c41afdc291d468c29 to your computer and use it in GitHub Desktop.
[JS ES6 Паттерн ИТЕРАТОР (iterator)] #Паттерны #ООП #js #ES6
/**
*
* ПАТТЕРН ИТЕРАТОР
*
Iterator — поведенческий шаблон проектирования. Представляет собой объект, позволяющий получить последовательный
доступ к элементам объекта-агрегата без использования описаний каждого из агрегированных объектов.
Например, такие элементы как дерево, связанный список, хеш-таблица и массив могут быть пролистаны (и модифицированы)
с помощью объекта Итератор.
Перебор элементов выполняется объектом итератора, а не самой коллекцией.
Особенностью полноценно реализованного итератора является то, что код, использующий итератор, может ничего не знать
о типе итерируемого агрегата.
*/
// using Iterator
class IteratorClass {
constructor(data) {
this.index = -1;
this.data = data;
this.done = false;
this.checkDataType(data);
}
checkDataType(data) { // Проверяем получен массив или объект
if (Array.isArray(data)) { // Перебор массива
this.collectionLength = this.data.length - 1;
this.collection = this.data;
this.type = 'array';
} else if (!Array.isArray(data) && typeof data == 'object') { // Перебор объекта
this.collectionLength = Object.keys(this.data).length - 1;
this.collection = Object.values(this.data);
this.type = 'object';
} else {
throw new Error(`${this.constructor.name} получил data которую не может итерировать - ${typeof data}`)
}
}
next() {
if (this.index < this.collectionLength) {
this.index++;
return {key: Object.keys(this.data)[this.index], value: this.collection[this.index],
done: false, index: this.index, type: this.type};
} else {
this.done = true;
return {done: true, msg: 'достигнут конец коллекции', index: this.index, type: this.type};
}
}
prev() {
if (this.done) {
this.done = false;
this.index = this.collectionLength + 1;
}
this.index--;
if (this.index > -1) {
return {key: Object.keys(this.data)[this.index], value: this.collection[this.index],
done: false, index: this.index, type: this.type};
} else {
this.index = -1;
return {done: this.done, msg: 'достигнуто начало коллекции', index: this.index, type: this.type};
}
}
}
// usage Iterator
console.log('Итерируем массив:');
const gen = new IteratorClass(['Hi', 'Hello', 'Bye']);
console.log(gen.next());
console.log(gen.next());
console.log(gen.next());
console.log(gen.next());
console.log(gen.next());
console.log(gen.prev());
console.log(gen.prev());
console.log(gen.prev());
console.log(gen.prev());
console.log(gen.next());
console.log('Итерируем объект:');
const obj = new IteratorClass({a: '1h', b: '2o', c: '3Bye'});
console.log(obj.next());
console.log(obj.next());
console.log(obj.next());
console.log(obj.next());
console.log(obj.prev());
console.log(obj.prev());
console.log(obj.prev());
console.log(obj.prev());
console.log(obj.prev());
console.log(obj.prev());
console.log(obj.prev());
console.log(obj.next());
console.log('Итерируем строку:'); // выдаст ошибку, итератор не настроен на строки
const string = new IteratorClass('1hello');
console.log(string.next());
console.log(string.next());
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment