Enum — 컬렉션(Enumerable)을 다루는 함수들
Enum — 컬렉션(Enumerable)을 다루는 함수들
Enum은 컬렉션(이를 enumerable이라고 불러요)을 다루는 함수들을 모아둔 모듈이에요.
Elixir에서 enumerable은 Enumerable 프로토콜을 구현한 모든 자료형을 말해요. 리스트([1, 2, 3]), 맵(%{foo: 1, bar: 2}), 범위(1..3)가 enumerable로 쓰이는 흔한 자료형이에요.
iex> Enum.map([1, 2, 3], fn x -> x * 2 end)
[2, 4, 6]
iex> Enum.sum([1, 2, 3])
6
iex> Enum.map(1..3, fn x -> x * 2 end)
[2, 4, 6]
iex> map = %{"a" => 1, "b" => 2}
iex> Enum.map(map, fn {k, v} -> {k, v * 2} end)
[{"a", 2}, {"b", 4}]
언어에는 이 외에도 많은 enumerable이 있어요. MapSet, 그리고 File.stream!/3이 반환하는 자료형처럼 파일을 enumerable처럼 순회할 수 있게 해주는 것도 있죠. Enum 모듈의 모든 함수에 대한 전체적인 개요는 Enum 치트시트(cheatsheet)를 보세요.
출처: Enum
본문
성능과 특성
이 모듈의 함수들은 선형 시간(linear time) 으로 동작해요. 즉 연산에 걸리는 시간이 enumerable의 길이와 같은 비율로 늘어나요. 예를 들어 Enum.map/2 같은 연산이 그렇죠. 애초에 리스트의 모든 요소를 순회하려면 리스트가 길수록 순회할 요소가 많아지고 시간도 더 걸릴 수밖에 없어요. 이런 선형 동작은 count/1, member?/2, at/2 같은 연산에서도 기대할 수 있어요. Elixir는 자료형이 성능 좋은 변형을 제공하는 걸 허용하지만, 언제나 그런 건 아니에요. Enum 모듈은 다양한 자료형과 함께 동작하도록 만들어졌는데, 모든 자료형이 최적화된 동작을 제공할 수는 없기 때문이에요.
마지막으로, Enum 모듈의 함수는 즉시(eager) 동작해요. 함수가 호출되는 순간 enumerable을 순회하죠. 이는 무한 enumerable을 다룰 때 특히 위험해요. 그런 경우에는 컬렉션을 순회하지 않고 계산을 느긋하게(lazily) 표현할 수 있게 해주는 Stream 모듈을 써야 해요. Stream 모듈 문서에 예시와 설명이 있어요.
대표 함수들
Enum에는 자료형을 다루는 함수가 아주 많아요. 주요 흐름만 빠르게 훑어볼게요.
- 매핑:
map/2는 각 요소에 함수를 적용해 결과 리스트를 반환해요.map_every/3는 n번째마다 적용하고,flat_map/2는 매핑 후 결과를 한 겹만 펼쳐요. - 필터링:
filter/2는 함수가 참인 요소만 남기고,reject/2는 그 반대예요. - 축약(누산):
reduce/3는 accumulator(누산기)를 이어가며 함수를 적용해 하나의 값으로 줄여요.map_reduce/3,scan/3,reduce_while/3도 같은 결의 함수예요. - 집계:
count/1,sum/1,product/1,frequencies/1등이 있어요. - 정렬:
sort/2,sort_by/3,min/2,max/2,min_by/3,max_by/3등이 있어요. 구조체를 비교할 때는 모듈을 sorter로 넘겨요. - 자르기·나누기:
take/2,drop/2,split/2,slice/2등이 있어요. 음수 인덱스는 뒤에서부터 셉니다. - 연결·펼치기:
concat/2,uniq/1,dedup/1등이 있어요.dedup/1은 연속된 중복만,uniq/1은 컬렉션 전체 기준 중복을 제거해요. - 변환:
into/3는 enumerable을 collectable에 넣고,to_list/1은 리스트로 바꿔요. - 묶기:
chunk_every/3,chunk_by/2,group_by/3등이 있어요. - 병합(지퍼):
zip/2,zip_with/3,unzip/1등이 있어요.
전체 함수 목록과 각 시그니처, 인자 기본값, 상세 예시는 원문 문서의 Summary(함수 목록) 항목과 각 함수 문서를 참고하세요.
더 알아보기
- Enum 치트시트에서 각 함수를 데이터 예시와 함께 빠르게 훑을 수 있어요.
- 무한 컬렉션을 다룰 때는
Stream모듈 문서를 보세요. Enumerable프로토콜 문서에서 자체 enumerable을 구현하는 법을 배울 수 있어요.