λ°λ³΅μ(Iterators)
λ°λ³΅μ μ체λ TypeScript λλ ES6 κΈ°λ₯μ μλλλ€. λ°λ³΅μλ κ°μ²΄ μ§ν₯ νλ‘κ·Έλλ° μΈμ΄λ₯Ό μν νλ λμμΈ ν¨ν΄μ λλ€. μΌλ°μ μΌλ‘ λ€μ μΈν°νμ΄μ€λ₯Ό ꡬννλ κ°μ²΄μ λλ€.
interface Iterator<T> {
next(value?: any): IteratorResult<T>;
return?(value?: any): IteratorResult<T>;
throw?(e?: any): IteratorResult<T>;
}
μ΄ μΈν°νμ΄μ€λ κ°μ²΄μ μν μ§ν© λλ μνμ€(sequence)μμ κ°μ κ°μ Έμ¬ μ μμ΅λλ€.
IteratorResult
λ λ¨μν value
+done
μμ
λλ€.:
interface IteratorResult<T> {
done: boolean;
value: T;
}
μ΄λ€ Frameμ ꡬμ±νλ Component λͺ©λ‘μ ν¬ν¨νλ Frameμ κ°μ²΄κ° μλ€κ³ μμνμΈμ. λ€μκ³Ό κ°μ΄ λ°λ³΅μ μΈν°νμ΄μ€λ‘ μ΄ Frame κ°μ²΄μμ Componentλ₯Ό κ°μ Έμ¬ μ μμ΅λλ€.:
class Component {
constructor (public name: string) {}
}
class Frame implements Iterator<Component> {
private pointer = 0;
constructor(public name: string, public components: Component[]) {}
public next(): IteratorResult<Component> {
if (this.pointer < this.components.length) {
return {
done: false,
value: this.components[this.pointer++]
}
} else {
return {
done: true
}
}
}
}
let frame = new Frame("Door", [new Component("top"), new Component("bottom"), new Component("left"), new Component("right")]);
let iteratorResult1 = frame.next(); //{ done: false, value: Component { name: 'top' } }
let iteratorResult2 = frame.next(); //{ done: false, value: Component { name: 'bottom' } }
let iteratorResult3 = frame.next(); //{ done: false, value: Component { name: 'left' } }
let iteratorResult4 = frame.next(); //{ done: false, value: Component { name: 'right' } }
let iteratorResult5 = frame.next(); //{ done: true }
//It is possible to access the value of iterator result via the value property:
let component = iteratorResult1.value; //Component { name: 'top' }
λ°λ³΅νλ©΄ λ°λ³΅μ μ체λ TypeScript κΈ°λ₯μ΄ μλλλ€. μ΄ μ½λλ Iteratorμ IteratorResult μΈν°νμ΄μ€λ₯Ό λͺ μμ μΈ κ΅¬ν μμ΄λ μ λμν κ²μ λλ€. κ·Έλ¬λ μ½λ μΌκ΄μ±μ μν΄ κ³΅ν΅ ES6 interfacesλ₯Ό μ¬μ©νλ κ²μ΄ λ§€μ° μ μ©ν©λλ€.
λ€ μ’μ΅λλ€. λ μ μ©ν κ²μ
λλ€. ES6λ Iterable μΈν°νμ΄μ€κ° ꡬνλλ©΄ [Symbol.iterator] symbol
μ ν¬ν¨νλ iteratable protocolμ μ μνκ³ μμ΅λλ€.
//...
class Frame implements Iterable<Component> {
constructor(public name: string, public components: Component[]) {}
[Symbol.iterator]() {
let pointer = 0;
let components = this.components;
return {
next(): IteratorResult<Component> {
if (pointer < components.length) {
return {
done: false,
value: components[pointer++]
}
} else {
return {
done: true,
value: null
}
}
}
}
}
}
let frame = new Frame("Door", [new Component("top"), new Component("bottom"), new Component("left"), new Component("right")]);
for (let cmp of frame) {
console.log(cmp);
}
λΆννκ²λ μ΄ ν¨ν΄μμλ frame.next()
λ λμνμ§ μμ κ²μ΄κ³ λ€μ κ±°μΆμ₯μ€λ½κ² λ³΄μΌ κ²μ
λλ€. ꡬ쑰λ₯Ό μν΄ IterableIterator μΈν°νμ΄μ€λ₯Ό!
//...
class Frame implements IterableIterator<Component> {
private pointer = 0;
constructor(public name: string, public components: Component[]) {}
public next(): IteratorResult<Component> {
if (this.pointer < this.components.length) {
return {
done: false,
value: this.components[this.pointer++]
}
} else {
return {
done: true,
value: null
}
}
}
[Symbol.iterator](): IterableIterator<Component> {
return this;
}
}
//...
IterableIterator μΈν°νμ΄μ€λ‘ frame.next()
μ for
μν λͺ¨λ μ λμν©λλ€.
λ°λ³΅μλ μ νν κ°μ λ°λ³΅ν νμλ μμ΅λλ€. μ νμ μΈ μκ° νΌλ³΄λμΉ μμ΄μ λλ€.:
class Fib implements IterableIterator<number> {
protected fn1 = 0;
protected fn2 = 1;
constructor(protected maxValue?: number) {}
public next(): IteratorResult<number> {
var current = this.fn1;
this.fn1 = this.fn2;
this.fn2 = current + this.fn1;
if (this.maxValue != null && current >= this.maxValue) {
return {
done: true,
value: null
}
}
return {
done: false,
value: current
}
}
[Symbol.iterator](): IterableIterator<number> {
return this;
}
}
let fib = new Fib();
fib.next() //{ done: false, value: 0 }
fib.next() //{ done: false, value: 1 }
fib.next() //{ done: false, value: 1 }
fib.next() //{ done: false, value: 2 }
fib.next() //{ done: false, value: 3 }
fib.next() //{ done: false, value: 5 }
let fibMax50 = new Fib(50);
console.log(Array.from(fibMax50)); // [ 0, 1, 1, 2, 3, 5, 8, 13, 21, 34 ]
let fibMax21 = new Fib(21);
for(let num of fibMax21) {
console.log(num); //Prints fibonacci sequence 0 to 21
}
ES5 λμμΌλ‘ λ°λ³΅μλ₯Ό μ¬μ©νλ μ½λ λ§λ€κΈ°
μ μμ λ ES6 μ΄μ λμμ μꡬνμ§λ§, λμ JS μμ§μ΄ Symbol.iterator
λ₯Ό μ§μνλ€λ©΄ ES5 λμμμλ μλν μ μμ΅λλ€. μ΄λ ES5 λμμμ ES6 lib μ¬μ©νμ¬ (es6.d.tsλ₯Ό νλ‘μ νΈμ μΆκ°) μ»΅νμΌ νλ©΄ λ©λλ€. μ»΄νμΌλ μ½λλ node 4+, κ΅¬κΈ ν¬λ‘¬ κ·Έλ¦¬κ³ λ€λ₯Έ λΈλΌμ°μ μμ λμν κ²μ
λλ€.