본문 바로가기

Study/Today I Learn

[TIL] 2019.03.22

Array, Set, Map 인덱스 접근

Array 는 해당 인덱스로 접근이 가능하지만 Set, Map은 undefined 반환

> arr[1]
< 2
> set[1]
< undefined
> map[1]
< undefined

iterable과 iterator

iterable : [Symbol.iterator]() 를 가진 객체, ex) Array, Set, Map...

iterator : {value, done} 을 리턴하고, next()를 가진 객체

const arr_iter = arr[Symbol.iterator]()
const set_iter = set[Symbol.iterator]()
const map_iter = map[Symbol.iterator]()

let a_iter_res = arr_iter.next()
let s_iter_res = set_iter.next()
let m_iter_res = map_iter.next()

console.log(arr_iter)
// Array Iterator {}
console.log(set_iter)
// SetIterator {1, 2, 3}
console.log(map_iter)
// MapIterator {"a" => 1, "b" => 2, "c" => 3}

console.log(a_iter_res)
// {value: 1, done: false}
console.log(s_iter_res)
// {value: 1, done: false}
console.log(m_iter_res)
// {value: Array(2), done: false}

> 'next' in arr_iter
< true
> 'next' in set_iter
< true
> 'next' in map_iter
< true

arr, set, map 처럼 [Symbol.iterator]() 을 가지고 있는 객체를 iterable 이라하고 next()를 가지고 있고 {done, value} 객체를 가지고 있는 arr_iter, set_iter, map_iter 을 iterator라고 부른다.

이터러블 / 이터레이터 프로토콜

데이터 컬렉션을 순회하기 위한 규약, 둘을 합쳐 이터레이션 프로토콜 이라고 부름

[Symbol.iterator].next()

const arr = [1, 2, 3]
const iter = arr[Symbol.iterator]()

log(iter.next())
log(iter.next())
log(iter.next())
log(iter.next())

// {value: 1, done: false}
// {value: 2, done: false}
// {value: 3, done: false}
// {value: undefined, done: true}

next() 시 value의 값이 증가, 마지막에 done 값이 true 로 변하면서 끝을 알림

for of 와 이터레이터

for of 문은 단순히 인덱스를 순회하면서 값을 뽑는 것이 아니라, iterator 를 이용해서 next()done 값이 true가 되면 next()를 중지한다.

따라서 이터러블인 여러 객체를 for of 문으로 순회할 수 있게 된다.

well-formed iterater

[Symbol.iterator] iterator가 자기자신을 리턴하는 이터레이터

const arr = [1, 2, 3]
const iter = arr[Symbol.iterator]()

log(iter == iter[Symbol.iterator]()) // true
// well-formed iterater

사용자 정의 이터러블

const iterable = {
  [Symbol.iterator] () {
    let i = 3
    return {
      next() {
        return i == 0 ? {value: undefined ,done: true} : {value: i--, done: false }
      }
    }
  }
}
let iterator = iterable[Symbol.iterator]()

for (const a of iterable) log(a)
// 3 2 1

for (const a of iterator) log(a)
// Uncaught TypeError: iterator is not iterable

iterator를 well-formed iterater 로 만드러 for (const a of iterator) log(a) 를 오류없이 실행 시켜보겠다.

const iterable = {
  [Symbol.iterator] () {
    let i = 3
    return {
      next() {
        return i == 0 ? {value: undefined ,done: true} : {value: i--, done: false }
      },
      [Symbol.iterator] () {
        return this
      }
    }
  }
}
let iterator = iterable[Symbol.iterator]()

log(iterator.next())

for (const a of iterator) log(a)

// {value: 3, done: false}
// 2
// 1

'Study > Today I Learn' 카테고리의 다른 글

[TIL] 2019.03.30  (0) 2019.03.30
[TIL] 2019.03.24  (0) 2019.03.24
[TIL] 2019.03.21  (0) 2019.03.22
[TIL] 2019.03.20  (0) 2019.03.20
[TIL] 2019.03.18  (0) 2019.03.18