본문 바로가기

카테고리 없음

이터러블(Iterable) 객체

 

 

 

지난번 Array.from() 함수의 매개변수 조건에서 Iterable 이라는 단어를 보았다.

 

자바스크립트 배열

JavaScript 참고서 - JavaScript | MDN이 페이지는 JavaScript 언어에 대한 정보 보관소입니다. 이 참고서에 대해 더 읽어보세요.developer.mozilla.org  배열의 형태let arr = [1, 2, 3, 4];console.log(arr); // [1, 2, 3, 4]  

notion7815.tistory.com

iterable 이라는건 어떤 종류의 데이터를 말하는 것일까?  

 

배열이 객체로써 동작하기에 사용할 수 있는 속성과 메서드가 생각보다 많다는것을 알고있을것이다. 예를들면

length 부터 시작하여 push(), pop(), shift()splice(), forEach(), map(), filter() 등의 함수들을 알고 있다. 오늘은

배열이 순회할 수 있는 자료구조인 iterable 객체이기에 사용가능한 함수들과 이터레이션의 개념을 한번 알아보자 

 

 

 

이터레이션 프로토콜 (iteration protocol)

iteration을 직역하면 반복, 순회 이다.

이터레이션 규약 (iteration protocol)은 데이터를 순회하기 위한 규약이다.

데이터 구조(배열, 리스트, 객체 등)의 요소를 순차적으로 접근하고 처리하는 과정을 의미한다. 

 

이터레이션 프로토콜에는 Iterable Protocol 과 Iterator Protocol이 있다.

 

프로그래밍에서 iterable은 순회(iteration)가 가능한 자료구조를 뜻하는 단어이다.

이터러블 객체는 객체 안에서 [Symbol.iterator]() 라는 함수를 호출했을때, iterator를 반환하는 객체를 말한다. 

 

iterator은 이터러블 객체의 요소를 순차적으로 접근할 수 있게 해주는 객체이다.

iterator 객체 안에서 next()라는 정의하면, 순차적으로 다음 요소를 반환한다.

 

이렇게 iteration이 가능한 자료구조로는 array, string, map, set 등이 있다.

 

이터러블 객체의 특징

  • for…of 문으로 순회할 수 있다
  • 스프레드 연산자를 사용할 수 있다.
  • Symbol.iterator를 반환하고 next()를 통해 value를 순회한다.

개념은 매우 복잡하지만 우리는 이미 이를 활용하고 있었다.

 for of 루프의 예시를 보자

const fruits = ['apple', 'banana', 'cherry'];

for (const fruit of fruits) {
    console.log(fruit); // apple, banana, cherry 출력
}

 

일반적인 for 루프의 변수선언, 조건문, 증감식 없이 어떻게 루프가 되는가에 대해 의문을 가져봤다면

이제는 배열이 이터레이션 프로토콜을 따르는 이터러블 객체이기에 for of으로 요소를 인식하여 순회하것임을 알 수 있을것이다.

정확히 말하자면 배열 안에 있는 [Symbol.iterator]() 함수를 호출하여 반환된 iterator 객체에서 next() 함수를 호출하고

next() 함수에 의해 item 값을 하나씩 반환아여 순회하는 메커니즘이다. 

 

이터레이터 함수를 자세히 펼쳐보자

const numbers = [1, 2, 3, 4, 5];

// 이터러블 객체의 Symbol.iterator 호출
const iterator = numbers[Symbol.iterator]();

console.log(iterator.next()); // { value: 1, done: false }
console.log(iterator.next()); // { value: 2, done: false }
console.log(iterator.next()); // { value: 3, done: false }
console.log(iterator.next()); // { value: 4, done: false }
console.log(iterator.next()); // { value: 5, done: false }
console.log(iterator.next()); // { value: undefined, done: true }

 

코드를 보면 배열 안에 있는 [Symbol.iterator]() 함수를 호출하고,

그 안에 있는 next 함수가 호출되면, value와 done 이라는 속성을 가진 객체를 반환한다.

위 코드에서는 결과도출을 위해 next를 한번씩 호출하였지만 for of 루프에서 사용하는것이 일반적이다.

 

value는 현재 이터레이터가 돌고있는 요소의 값이고, 

done은 이터레이션이 완료되었는지를 나타내는 불리언 값이다.

더 이상 반환할 값이 없으면 done은 true가 된다.

 

배열과 같은 기본 이터러블 객체라면 사용할 수 있는 함수들이 더 있다.

 

values()

배열이나 객체를 순환하여 값을 반환하는 이터레이터 반환한다.

const array = ['a', 'b', 'c'];

for (const item of array.values()) {
    console.log(item);
}
/*
a
b
c
*/

 

keys() 

배열이나 객체의 모든 키값(인덱스)를 포함하는 이터레이터를 반환

const array = ['a', 'b', 'c'];

for (const item of array.keys()) {
    console.log(item);
}
/*
0
1
2
*/

 

entries()

배열이나 객체의 각 요소의 키와 값을 둘다 반환하는데, [(key or index), value] 형태의 배열로 반환한다.

const array = ['a', 'b', 'c'];

for (const item of array.entries()) {
    console.log(item);
}
/*
[ 0, 'a' ]
[ 1, 'b' ]
[ 2, 'c' ]
*/

 

이 세 개 함수 역시 [Symbol.iterator] 함수와 동일하게 next() 를 호출하며 동작한다.

필요한 상황에 맞게 사용하면 될듯 하다.

const array = ['a', 'b', 'c'];

// 배열의 키-값 쌍 이터레이터 생성
const entryIterator = array.entries();

console.log(entryIterator.next()); // { value: [0, 'a'], done: false }
console.log(entryIterator.next()); // { value: [1, 'b'], done: false }
console.log(entryIterator.next()); // { value: [2, 'c'], done: false }
console.log(entryIterator.next()); // { value: undefined, done: true }

 

 

while 문에서 순회

마지막에 true를 반환하는 done의 특성을 사용하여 편리하게 사용가능하다

const numbers = [1, 2, 3, 4, 5];

const iterator = numbers[Symbol.iterator]();

while (true) {
    const item = iterator.next();
    if(item.done) break;

    console.log(item.value);
}

 

 

구글링 중 정리가 잘 된 곳이 있어서 링크

 

[모던 자바스크립트 튜토리얼] 5.6 iterable 객체

iterables, iterator

velog.io