Как сделать итератор из класса ES6
Как сделать итератор из класса ES6 таким же образом, как синтаксис JS1.7 SomeClass.prototype.__iterator__ = function() {...}
?
[РЕДАКТИРОВАТЬ 16:00]
Следующие работы:
class SomeClass {
constructor() {
}
*[Symbol.iterator]() {
yield '1';
yield '2';
}
//*generator() {
//}
}
an_instance = new SomeClass();
for (let v of an_instance) {
console.log(v);
}
Флаги WebStorm *[Symbol.iterator]()
с предупреждением "имя функции", непосредственно следуя за звездочкой, но в остальном это компилируется и отлично работает с Traceur. (Примечание. WebStorm не создает ошибок для *generator()
.)
Ответы
Ответ 1
Определите подходящий метод итератора. Например:
class C {
constructor() { this.a = [] }
add(x) { this.a.push(x) }
[Symbol.iterator]() { return this.a.values() }
}
Изменение: Пример использования:
let c = new C
c.add(1); c.add(2)
for (let i of c) console.log(i)
Ответ 2
Вам нужно указать свойство Symbol.iterator
для SomeClass
, которое возвращает iterator для экземпляров класса. Итератор должен иметь метод next()
, который, в свою очередь, возвращает объект с полями done
и value
. Упрощенный пример:
function SomeClass() {
this._data = [1,2,3,4];
}
SomeClass.prototype[Symbol.iterator] = function() {
var index = 0;
var data = this._data;
return {
next: function() {
return { value: data[++index], done: !(index in data) }
}
};
};
Или используя классы ES6 и функции стрелок:
class SomeClass {
constructor() {
this._data = [1,2,3,4];
}
[Symbol.iterator]() {
var index = -1;
var data = this._data;
return {
next: () => ({ value: data[++index], done: !(index in data) })
};
};
}
И использование:
var obj = new SomeClass();
for (var i of obj) { console.log(i) }
В обновленном вопросе вы поняли, что итератор класса через функцию генератора. Вы можете это сделать, но вы должны понимать, что итератор НЕ МОЖЕТ быть генератором. На самом деле итератором в es6 является любой объект, который имеет конкретный метод next()
Ответ 3
Здесь приведен пример для итерации над пользовательским классом 2d-матрицы в ES6
class Matrix {
constructor() {
this.matrix = [[1, 2, 9],
[5, 3, 8],
[4, 6, 7]];
}
*[Symbol.iterator]() {
for (let row of this.matrix) {
for (let cell of row) {
yield cell;
}
}
}
}
Использование такого класса будет
let matrix = new Matrix();
for (let cell of matrix) {
console.log(cell)
}
Что бы вывести
1
2
9
5
3
8
4
6
7
Ответ 4
Документация: итерационные протоколы
Пример класса, реализующий как протокол итератора, так и методы итерируемого протокола:
class MyCollection {
constructor(elements) {
if (!Array.isArray(elements))
throw new Error('Parameter to constructor must be array');
this.elements = elements;
}
// Implement "iterator protocol"
*iterator() {
for (let key in this.elements) {
var value = this.elements[key];
yield value;
}
}
// Implement "iterable protocol"
[Symbol.iterator]() {
return this.iterator();
}
}
Доступ к элементам с использованием любой техники:
var myCollection = new MyCollection(['foo', 'bar', 'bah', 'bat']);
// Access elements of the collection using iterable
for (let element of myCollection)
console.log('element via "iterable": ' + element);
// Access elements of the collection using iterator
var iterator = myCollection.iterator();
while (element = iterator.next().value)
console.log('element via "iterator": ' + element);
Ответ 5
Пример класса итератора ES6, который хранится в подобъекте:
class Iterator {
data;
constructor(data = {}) {
this.data = JSON.parse(JSON.stringify(data));
}
add(key, value) { this.data[key] = value; }
get(key) { return this.data[key]; }
[Symbol.iterator]() {
const keys = Object.keys(this.data).filter(key =>
this.data.hasOwnProperty(key));
const values = keys.map(key => this.data[key]).values();
return values;
}
}
Ответ 6
Ниже я нашел статью, написанную Максом, которая лучше всего объясняет, как использовать концепции итераторов и генераторов в любой пользовательской коллекции, такой как ArrayList или LinkedList, чтобы можно было использовать for...of
цикла конструкции для итерации.
https://medium.com/dailyjs/es6-iterators-and-generators-by-example-d728bfa00c3a
Ответ 7
Ниже я нашел статью, которая лучше всего объясняет написанное Максом.
https://medium.com/dailyjs/es6-iterators-and-generators-by-example-d728bfa00c3a