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을 구현하는 법을 배울 수 있어요.