반복자 만들기
16096 단어 programmingjavascriptnodebeginners
배열과 맵은 사물의 모음이며 반복하기 전에 명시적으로 정의해야 합니다. 빈 배열이나 선언으로 시작할 수 있으며 여기에 항목을 푸시할 수 있습니다. 예시:
const things = ['headphone', 'keyboard', 'mouse']
const friends = {
tomo: 'nuxt expert',
jt: 'writes nasty sqls',
deco: 'the leader',
van: 'php guru'
}
things.push('cables')
// one of the ways of iterating arrays
for (const thing of things) {
console.log(thing)
}
// iterate the key of objects
for (const name in friends) {
console.log(`${name} - ${friends[name]}`)
}
배열이나 객체를 반복하는 방법에는 여러 가지가 있습니다. 몇 가지 예를 들자면:
for(const i = 0; i < arr.length; i+=1)
for...of
MDNfor...in
MDNwhile()
MDNArray.forEach
MDNArray.map
MDNArray.filter
MDNArray.reduce
MDN배열이나 객체(Map, Set 등)에 대한 한 가지는 무엇을 얻고 있는지 알고 있다는 것입니다. 배열에 항목을 푸시할 수 있지만 무엇을 푸시했는지 알고 있습니다. 역동적이지 않습니다. 배열에 있는 항목이 있으면 제거할 때까지 그대로 유지됩니다. 또한 메모리에서 해당 공간을 차지합니다.
반복자 프로토콜
value
반복에서 얻는 것next
을 계산하는 동적 배열이 있다면 어떨까요? 당신이 만든 공식을 기반으로 작동한다면 어떨까요? 반복자 패턴을 사용해야 합니다. 구현이 매우 간단하다는 것을 알 수 있습니다. JS 프로그래머들 사이에서 잘 알려져 있고 다른 언어에서도 따르는 프로토콜입니다. 반복자는 next()
메서드가 있는 객체입니다. 객체에서 next()
함수를 호출하면 두 가지 속성이 있는 객체인 반복자 결과를 얻을 수 있습니다. 즉, 반복자의 상태를 유지하는 부울 값인 done
와 반환하려는 항목을 유지하는 value
입니다. 간단한 범위 반복자를 만들어 봅시다. 이 범위 반복자는 시작, 끝 및 단계를 제공하여 숫자 범위를 만들 수 있게 해줍니다.// iterator protocol: an agreed interface
function numberRangeIterator(start, end, step) {
let index = start
return {
next() {
if (index > end) {
return { done: true, value: 'thanks for using me' } // value is optional here but you can use it to return meta info
}
const value = index
index += step
return { done: false, value }
}
}
}
const iterator = numberRangeIterator(3, 30, 3)
let iteratorResult = iterator.next()
while (!iteratorResult.done) {
console.log(iteratorResult.value)
iteratorResult = iterator.next()
}
알겠어? 매우 간단하면서도 강력합니다. 두 가지 참고 사항:
next
함수는 더 이상 요소가 없음을 나타내기 위해 done: true
를 반환하고 반대해야 합니다. 그러나 필수는 아니며 영원히 실행되는 반복자를 가질 수 있습니다! done: false
를 갖거나 {value}
만 반환할 수 있으며 위의 코드는 잘 작동할 것입니다.function randomNumberIterator() {
return {
next() {
return { done: false, value: Math.random() }
}
}
}
const rIterator = randomNumberIterator()
let rIteratorResult = rIterator.next()
while (!rIteratorResult.done) {
console.log(rIteratorResult.value)
rIteratorResult = rIterator.next()
}
위의 이터레이터를 언제 사용할지 생각할 수 없지만 난수를 무한히 생성할 수 있는 이터레이터를 보여주고 싶었습니다.
반복 가능한 프로토콜
Iterable 프로토콜은 모든 객체가 반복자를 반환하도록 JS 언어 내에서 표준을 정의함으로써 한 단계 더 나아갑니다.
iterable
는 [Symbol.iterator]
라는 반복자 메서드를 구현하는 객체입니다. 위에서 언급한 이터레이터에 이터러블을 사용할 때 가장 좋은 점은 for...of
와 같은 배열을 반복하는 데 JS 네이티브 API를 사용할 수 있다는 것입니다. numberRangeIterator
를 iterable로 빌드해 봅시다.class NumberRange {
constructor(start, end, step) {
this.start = start
this.end = end
this.step = step
}
// for an object/class to classify as iterable
// it has to implement [Symbol.iterator]
[Symbol.iterator]() {
let index = this.start
return {
next: () => {
if (index > this.end) {
return { done: true }
}
const value = index
index += this.step
return { value }
}
}
}
}
const myRange = new NumberRange(3, 30, 3)
for (const num of myRange) {
console.log(num)
}
Iterable 클래스를 정의하는 데 거의 동일한 양의 코드가 사용되었으며 대부분의 코드를 재사용했습니다. 그러나 아름다움은 반복자를 사용하는 방식에 있습니다.
for...of
를 사용하면 깔끔하고 간결해 보입니다. 나는 위의 while
루프보다 이것을 선호합니다. 하지만 여기서 멈추지 않습니다. 이 반복 가능 항목을 사용할 수 있는 다른 방법이 있습니다. 스프레드 연산자와 함께 사용할 수 있습니다.const myRange2 = new NumberRange(5, 20, 4)
console.log(...myRange2) // prints 5 9 13 17
또는 분해 및 할당
const myRange2 = new NumberRange(5, 20, 4)
const [first, second, third] = myRange2
console.log(first, second, third) // prints 5 9 13
Array.from(iterable)
, Set([iterable])
, Promise.all(iterable)
및 심지어 stream.Readable.from(iterable)
와 같은 반복 가능 항목을 전달할 수 있는 반복 가능 항목을 허용하는 다른 JS 내장 API가 있습니다.Read more about iterators here . 일반 배열처럼 취급할 수 있지만 본질적으로 동적이며 필요할 때만 값을 계산합니다. 그러나 비동기 반복자의 영역에 들어가기 시작하면 상황이 약간 복잡해집니다. 그러나 그것은 또 다른 날입니다.
Reference
이 문제에 관하여(반복자 만들기), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://dev.to/dnafication/building-iterators-1ebb텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)